UNPKG

moleculer-iam

Version:

Centralized IAM module for moleculer. Including a certified OIDC provider and an Identity provider for user profile, credentials, and custom claims management. Custom claims could be defined/updated by declarative schema which contains claims validation a

125 lines 5.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAPIGatewayMixin = void 0; const tslib_1 = require("tslib"); const fs_1 = tslib_1.__importDefault(require("fs")); const path_1 = tslib_1.__importDefault(require("path")); // will publish public API only if IAM service is connected to API gateway service. const api = { branch: "master", protocol: { REST: { basePath: "/iam", description: "Issue access token for API gateway on purpose of debugging.", routes: [ { path: "/login", method: "GET", call: { action: "iam.$login", params: { request: "@context.request", callback: "@query.callback", scope: "@query.scope", }, }, }, { path: "/login/callback", method: "GET", call: { action: "iam.$loginCallback", params: {}, }, } ], }, }, policy: {}, }; function createAPIGatewayMixin(gatewayURI) { const URIs = [ `${gatewayURI}`, `https://localhost:9090` ]; const loginURIs = URIs.map(uri => uri + "/iam/login"); const loginCallbackURIs = loginURIs.map(uri => uri + "/callback"); const clientParams = { client_id: "api-gateway", client_name: "API Gateway", client_uri: gatewayURI, redirect_uris: loginCallbackURIs, skip_consent: true, }; const loginCallbackHTML = fs_1.default.readFileSync(path_1.default.join(__dirname, "./api.login.callback.html")).toString("utf-8"); const mixin = { metadata: { api, }, events: { "$broker.started": { async handler() { // create/update API gateway client const client = await this.broker.call("iam.client.find", { id: clientParams.client_id }, { nodeID: this.broker.nodeID }); if (!client) { await this.broker.call("iam.client.create", clientParams, { nodeID: this.broker.nodeID }); } else { await this.broker.call("iam.client.update", clientParams, { nodeID: this.broker.nodeID }); } this.broker.logger.info(`API Gateway client initialized for debugging purpose: ${loginURIs.join(", ")}`); }, }, }, actions: { $report: { handler({ params: { table, messages } }) { this.broker.logger.info(table); }, }, $login: { params: { callback: { type: "string", optional: true, }, scope: { type: "string", optional: true, }, }, async handler({ params: { request, callback, scope = "" } }) { // gather all scopes except offline access scope const givenScopes = scope.split(" ").filter(s => !!s); const scopesSet = new Set(givenScopes.length > 0 ? givenScopes : await this.idp.claims.getActiveClaimsSchemata().then(schemata => schemata.map(s => s.scope))); scopesSet.delete("offline_access"); const scopes = [...scopesSet]; // create authorization endpoint const redirectURI = request.host && loginCallbackURIs.find(uri => uri.includes(request.host)) || loginCallbackURIs[0]; const callbackURI = callback || request && request.referer || gatewayURI; const nonce = Math.floor(Math.random() * 10000).toString(); const authURI = `${this.op.issuer}/op/auth?client_id=${clientParams.client_id}&response_type=code%20token&scope=${encodeURIComponent(scopes.join(" "))}&prompt=login&redirect_uri=${encodeURIComponent(redirectURI)}&state=${encodeURIComponent(callbackURI)}&nonce=${nonce}`; return { $status: 303, $headers: { "Location": authURI, }, }; }, }, $loginCallback: { params: {}, handler() { // handle token and redirection in client-side (#id_token=xxx&acess_token=xxx&state=xxx...) return { $status: 200, $body: loginCallbackHTML, }; }, }, }, }; return mixin; } exports.createAPIGatewayMixin = createAPIGatewayMixin; //# sourceMappingURL=api.js.map