UNPKG

graphile-build-pg

Version:

Build a GraphQL schema by reflection over a PostgreSQL schema. Easy to customize since it's built with plugins on graphile-build

99 lines (97 loc) 3.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _jsonwebtoken = require("jsonwebtoken"); var PgJWTPlugin = function PgJWTPlugin(builder, { pgJwtTypeIdentifier, pgJwtSecret, pgJwtSignOptions }) { builder.hook("init", (_, build) => { const { newWithHooks, pgSql: sql, pgIntrospectionResultsByKind: introspectionResultsByKind, pgRegisterGqlTypeByTypeId, pg2GqlMapper, pgTweaksByTypeId, pgTweakFragmentForTypeAndModifier, graphql: { GraphQLScalarType }, inflection, pgParseIdentifier: parseIdentifier, describePgEntity } = build; if (!pgJwtTypeIdentifier) { return _; } if (!pgJwtSecret) { throw new Error("pgJwtTypeIdentifier was specified without pgJwtSecret"); } const { namespaceName, entityName: typeName } = parseIdentifier(pgJwtTypeIdentifier); const compositeClass = introspectionResultsByKind.class.find(table => !table.isSelectable && !table.isInsertable && !table.isUpdatable && !table.isDeletable && table.name === typeName && table.namespaceName === namespaceName); if (!compositeClass) { throw new Error(`Could not find JWT type '"${namespaceName}"."${typeName}"'`); } const compositeType = compositeClass.type; if (!compositeType) { throw new Error("Could not determine the type for JWT type"); } if (pg2GqlMapper[compositeType.id]) { throw new Error("JWT type has already been overridden?"); } const attributes = compositeClass.attributes; const compositeTypeName = inflection.tableType(compositeClass); // NOTE: we deliberately do not create an input type pgRegisterGqlTypeByTypeId(compositeType.id, cb => { const JWTType = newWithHooks(GraphQLScalarType, { name: compositeTypeName, description: build.wrapDescription("A JSON Web Token defined by [RFC 7519](https://tools.ietf.org/html/rfc7519) which securely represents claims between two parties.", "type"), serialize(value) { const token = attributes.reduce((memo, attr) => { if (attr.name === "exp") { memo[attr.name] = value[attr.name] ? parseFloat(value[attr.name]) : undefined; } else { memo[attr.name] = value[attr.name]; } return memo; }, {}); return (0, _jsonwebtoken.sign)(token, pgJwtSecret, Object.assign({}, pgJwtSignOptions, token.aud || pgJwtSignOptions && pgJwtSignOptions.audience ? null : { audience: "postgraphile" }, token.iss || pgJwtSignOptions && pgJwtSignOptions.issuer ? null : { issuer: "postgraphile" }, token.exp || pgJwtSignOptions && pgJwtSignOptions.expiresIn ? null : { expiresIn: "1 day" })); } }, { __origin: `Adding JWT type based on ${describePgEntity(compositeType)}`, isPgJwtType: true }); cb(JWTType); pg2GqlMapper[compositeType.id] = { map: value => { if (!value) return null; const values = Object.values(value); if (values.some(v => v != null)) { return value; } return null; }, unmap: () => { throw new Error("We don't support passing a JWT token into GraphQL currently"); } }; pgTweaksByTypeId[compositeType.id] = fragment => sql.fragment`json_build_object(${sql.join(compositeClass.attributes.map(attr => sql.fragment`${sql.literal(attr.name)}::text, ${pgTweakFragmentForTypeAndModifier(sql.fragment`(${fragment}).${sql.identifier(attr.name)}`, attr.type, attr.typeModifier, {})}`), ", ")})`; }); return _; }, ["PgJWT"], [], ["PgIntrospection"]); }; exports.default = PgJWTPlugin; //# sourceMappingURL=PgJWTPlugin.js.map