UNPKG

iffe-oidc

Version:
141 lines 12.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OIDCManager = void 0; const RelyingParty = require("@solid/oidc-rp"); const qs = require("querystring"); const jwt = require("jsonwebtoken"); const cross_fetch_1 = require("cross-fetch"); class OIDCManager { constructor(redisClient, options) { this._rps = {}; this._rpConfigDB = redisClient.getRedisDB(2); this._sessionDB = redisClient.getRedisDB(1); this._redirectUri = options.redirect_uri; this._clientId = options.client_id; this._clientSecret = options.client_secret; this._authEndpoint = options.auth_endpoint; this._tokenEndpoint = options.token_endpoint; this._registration = { grant_types: ['implicit'], redirect_uris: [options.redirect_uri], response_types: ['id_token token'], scope: 'openid profile', }; // TODO: allow client_id to be set after dynamic registration options.client_id && (this._registration.client_id = options.client_id); this._options = { defaults: { authenticate: { redirect_uri: options.redirect_uri, response_type: 'id_token token', scope: 'openid profile', }, }, }; } async createSession(providerId) { const relyingParty = await this._getRelyingParty(providerId); const authnState = {}; const authnUrl = await relyingParty.createRequest({ redirect_uri: this._redirectUri }, authnState); const { state: sessionKey } = qs.parse(authnUrl.substr(authnUrl.indexOf('?') + 1)); if (typeof sessionKey !== 'string') { throw new Error("authnUrl's state is not a string: " + authnUrl); } await this._sessionDB.set(sessionKey, { providerId, authnState, session: {}, authnUrl, }); return this._authCodeUrl(authnUrl); } async _getRelyingParty(providerId) { if (!this._rps[providerId]) { await this._initRelyingParty(providerId); } return this._rps[providerId]; } async _initRelyingParty(providerId) { const rpConfig = await this._rpConfigDB.get(providerId); if (rpConfig) { this._rps[providerId] = await RelyingParty.from(rpConfig); return; } this._rps[providerId] = await RelyingParty.register(providerId, Object.assign(Object.assign({}, this._registration), { issuer: providerId }), this._options); await this._rpConfigDB.set(providerId, this._rps[providerId]); return; } _authCodeUrl(authnUrl) { if (!this._authEndpoint) return authnUrl; const { client_id, state } = qs.parse(authnUrl); return (this._authEndpoint + '?' + qs.stringify({ client_id, redirect_uri: this._redirectUri, scope: 'openid profile', response_type: 'code', state, prompt: 'consent', })); } async getIdToken(code) { const body = new URLSearchParams(); body.append('client_id', this._clientId); body.append('client_secret', this._clientSecret); body.append('redirect_uri', this._redirectUri); body.append('grant_type', 'authorization_code'); body.append('code', code); const response = await cross_fetch_1.default(this._tokenEndpoint, { method: 'POST', body, }); if (!response.ok) { throw new Error(`Failed to get id_token from code: ` + response.statusText); } const { id_token } = await response.json(); return jwt.verify(id_token, this._clientSecret); } async confirmSession(sessionKey, account) { const accessUrl = await this._obtainPodConsent(sessionKey, account); const { providerId, authnState } = await this._sessionDB.get(sessionKey); const relyingParty = await this._getRelyingParty(providerId); // TODO: error handling const session = await relyingParty.validateResponse(accessUrl, authnState); await this._sessionDB.set(sessionKey, { providerId, authnState, session, authnUrl: '', }); } async _obtainPodConsent(sessionKey, account) { const authnUrl = await this.getAuthnUrl(sessionKey); const tokenUrl = this._getTokenUrl(authnUrl, account); const res = await cross_fetch_1.default(tokenUrl, { redirect: 'manual' }); if (res.status !== 302) { throw new Error('Failed to obtain pod consent: ' + account); } return res.headers.get('Location') || ''; } _getTokenUrl(authnUrl, account) { let url = new URL(authnUrl); url.pathname = '/token'; url.searchParams.append('account', account); return url.toString(); } async getAuthnUrl(sessionKey) { const { authnUrl } = await this._sessionDB.get(sessionKey); return authnUrl; } async getSession(sessionKey) { const { session } = await this._sessionDB.get(sessionKey); return session; } async deleteSession(sessionKey) { await this._sessionDB.del(sessionKey); } } exports.OIDCManager = OIDCManager; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT2lkY01hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvT2lkY01hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0NBQWdEO0FBQ2hELGtDQUFrQztBQUNsQyxvQ0FBb0M7QUFDcEMsNkNBQXFDO0FBRXJDLE1BQWEsV0FBVztJQWN0QixZQUFZLFdBQWdCLEVBQUUsT0FBWTtRQWJsQyxTQUFJLEdBQTJDLEVBQUUsQ0FBQztRQWN4RCxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0MsSUFBSSxDQUFDLFVBQVUsR0FBRyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTVDLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztRQUN6QyxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUM7UUFDbkMsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDO1FBQzNDLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQztRQUMzQyxJQUFJLENBQUMsY0FBYyxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUM7UUFFN0MsSUFBSSxDQUFDLGFBQWEsR0FBRztZQUNuQixXQUFXLEVBQUUsQ0FBQyxVQUFVLENBQUM7WUFDekIsYUFBYSxFQUFFLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQztZQUNyQyxjQUFjLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQztZQUNsQyxLQUFLLEVBQUUsZ0JBQWdCO1NBQ3hCLENBQUM7UUFFRiw2REFBNkQ7UUFDN0QsT0FBTyxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUV4RSxJQUFJLENBQUMsUUFBUSxHQUFHO1lBQ2QsUUFBUSxFQUFFO2dCQUNS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