extract server auth into auth.js

This is just a nice cleanup, but it also supports a test mock I want to do next, to mock logins for the test db without having to round-trip to auth0.
This commit is contained in:
Emi Matchu 2020-10-22 19:53:10 -07:00
parent 5f3ac956e3
commit acdf6209ca
2 changed files with 47 additions and 44 deletions

46
src/server/auth.js Normal file
View file

@ -0,0 +1,46 @@
const util = require("util");
const jwtVerify = util.promisify(require("jsonwebtoken").verify);
const jwksClient = require("jwks-rsa");
const jwks = jwksClient({
jwksUri: "https://openneo.us.auth0.com/.well-known/jwks.json",
});
async function getJwtKey(header, callback) {
jwks.getSigningKey(header.kid, (err, key) => {
if (err) {
return callback(null, signingKey);
}
const signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
});
}
async function getUserIdFromToken(token) {
if (!token) {
return null;
}
let payload;
try {
payload = await jwtVerify(token, getJwtKey, {
audience: "https://impress-2020.openneo.net/api",
issuer: "https://openneo.us.auth0.com/",
algorithms: ["RS256"],
});
} catch (e) {
console.error(`Invalid auth token: ${token}\n${e}`);
return null;
}
const subMatch = payload.sub.match(/auth0\|impress-([0-9]+)/);
if (!subMatch) {
console.log("Unexpected auth token sub format", payload.sub);
return null;
}
const userId = subMatch[1];
return userId;
}
module.exports = { getUserIdFromToken };

View file

@ -1,10 +1,7 @@
const util = require("util");
const { beelinePlugin } = require("./lib/beeline-graphql"); const { beelinePlugin } = require("./lib/beeline-graphql");
const { gql, makeExecutableSchema } = require("apollo-server"); const { gql, makeExecutableSchema } = require("apollo-server");
const jwtVerify = util.promisify(require("jsonwebtoken").verify);
const jwksClient = require("jwks-rsa");
const { getUserIdFromToken } = require("./auth");
const connectToDb = require("./db"); const connectToDb = require("./db");
const buildLoaders = require("./loaders"); const buildLoaders = require("./loaders");
const { svgLoggingPlugin } = require("./types/AppearanceLayer"); const { svgLoggingPlugin } = require("./types/AppearanceLayer");
@ -53,46 +50,6 @@ if (process.env["NODE_ENV"] !== "test") {
plugins.push(beelinePlugin); plugins.push(beelinePlugin);
} }
const jwks = jwksClient({
jwksUri: "https://openneo.us.auth0.com/.well-known/jwks.json",
});
async function getJwtKey(header, callback) {
jwks.getSigningKey(header.kid, (err, key) => {
if (err) {
return callback(null, signingKey);
}
const signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
});
}
async function getUserIdFromToken(token) {
if (!token) {
return null;
}
let payload;
try {
payload = await jwtVerify(token, getJwtKey, {
audience: "https://impress-2020.openneo.net/api",
issuer: "https://openneo.us.auth0.com/",
algorithms: ["RS256"],
});
} catch (e) {
console.error(`Invalid auth token: ${token}\n${e}`);
return null;
}
const subMatch = payload.sub.match(/auth0\|impress-([0-9]+)/);
if (!subMatch) {
console.log("Unexpected auth token sub format", payload.sub);
return null;
}
const userId = subMatch[1];
return userId;
}
const config = { const config = {
schema, schema,
context: async ({ req }) => { context: async ({ req }) => {