@graphql-yoga/plugin-jwt
Version:
jwt plugin for GraphQL Yoga.
114 lines (113 loc) • 3.95 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractFromHeader = extractFromHeader;
exports.extractFromCookie = extractFromCookie;
exports.extractFromConnectionParams = extractFromConnectionParams;
exports.badRequestError = badRequestError;
exports.unauthorizedError = unauthorizedError;
exports.createInlineSigningKeyProvider = createInlineSigningKeyProvider;
exports.createRemoteJwksSigningKeyProvider = createRemoteJwksSigningKeyProvider;
const graphql_yoga_1 = require("graphql-yoga");
const jwks_rsa_1 = require("jwks-rsa");
require("@whatwg-node/server-plugin-cookies");
const promise_helpers_1 = require("@whatwg-node/promise-helpers");
function extractFromHeader(options) {
return ({ request }) => {
if (!request) {
return;
}
const header = request.headers.get(options.name);
if (header == null) {
return;
}
if (!options.prefix) {
const parts = header.split(' ').map(s => s.trim());
const [prefix, token] = parts.length === 1 ? [undefined, parts[0]] : parts;
if (!token) {
throw badRequestError(`Authentication header was set, but token is missing.`);
}
return {
prefix,
token,
};
}
const [prefix, token] = header.split(' ').map(s => s.trim());
if (prefix !== options.prefix) {
throw badRequestError(`Invalid JWT authentication token prefix.`);
}
if (!token) {
throw badRequestError(`Authentication header was set, but token is missing.`);
}
return {
prefix,
token,
};
};
}
function extractFromCookie(options) {
return ({ request }) => {
if (!request) {
return;
}
const cookieStore = request.cookieStore;
if (!cookieStore) {
throw new Error('Cookie store is not available on request. Please make sure to configure the cookie plugin.');
}
return (0, promise_helpers_1.handleMaybePromise)(() => cookieStore.get(options.name), cookie => {
if (!cookie) {
return;
}
return {
prefix: undefined,
token: cookie.value,
};
});
};
}
function extractFromConnectionParams(options) {
return ({ serverContext }) => {
if (typeof serverContext?.['connectionParams'] === 'object' &&
serverContext['connectionParams'] != null &&
options.name in serverContext['connectionParams'] &&
typeof serverContext['connectionParams'] === 'object' &&
serverContext['connectionParams'] != null &&
options.name in serverContext['connectionParams']) {
// @ts-expect-error - TS doesn't understand the type guard above
const token = serverContext['connectionParams'][options.name];
if (typeof token === 'string') {
return {
prefix: undefined,
token,
};
}
}
return;
};
}
function badRequestError(message, options) {
return (0, graphql_yoga_1.createGraphQLError)(message, {
extensions: {
http: {
status: 400,
},
},
...options,
});
}
function unauthorizedError(message, options) {
return (0, graphql_yoga_1.createGraphQLError)(message, {
extensions: {
http: {
status: 401,
},
},
...options,
});
}
function createInlineSigningKeyProvider(signingKey) {
return () => signingKey;
}
function createRemoteJwksSigningKeyProvider(jwksClientOptions) {
const client = new jwks_rsa_1.JwksClient(jwksClientOptions);
return kid => client.getSigningKey(kid)?.then(r => r.getPublicKey());
}
;