diff --git a/src/oidc.js b/src/oidc.js index babb03b77..569ac3619 100644 --- a/src/oidc.js +++ b/src/oidc.js @@ -184,58 +184,6 @@ class Account { store.set(this.accountId, this); } - /** - * @param use - can either be "id_token" or "userinfo", depending on - * where the specific claims are intended to be put in. - * @param scope - the intended scope, while oidc-provider will mask - * claims depending on the scope automatically you might want to skip - * loading some claims from external resources etc. based on this detail - * or not return them in id tokens but only userinfo and so on. - */ - async claims(use, scope) { // eslint-disable-line no-unused-vars - if (this.profile) { - return { - sub: this.accountId, // it is essential to always return a sub claim - email: this.profile.email, - email_verified: this.profile.email_verified, - family_name: this.profile.family_name, - given_name: this.profile.given_name, - locale: this.profile.locale, - name: this.profile.name, - }; - } - - return { - sub: this.accountId, // it is essential to always return a sub claim - - address: { - country: '000', - formatted: '000', - locality: '000', - postal_code: '000', - region: '000', - street_address: '000', - }, - birthdate: '1987-10-16', - email: 'johndoe@example.com', - email_verified: false, - family_name: 'Doe', - gender: 'male', - given_name: 'John', - locale: 'en-US', - middle_name: 'Middle', - name: 'John Doe', - nickname: 'Johny', - phone_number: '+49 000 000000', - phone_number_verified: false, - picture: 'http://lorempixel.com/400/200/', - preferred_username: 'johnny', - profile: 'https://johnswebsite.com', - updated_at: 1454704946, - website: 'http://example.com', - zoneinfo: 'Europe/Berlin', - }; - } static async findByFederated(provider, claims) { const id = `${provider}.${claims.sub}`; @@ -434,6 +382,37 @@ function attachInteractionRoutes(routePrefix, app, provider) { }); } +/** + * @param use - can either be "id_token" or "userinfo", depending on + * where the specific claims are intended to be put in. + * @param scope - the intended scope, while oidc-provider will mask + * claims depending on the scope automatically you might want to skip + * loading some claims from external resources etc. based on this detail + * or not return them in id tokens but only userinfo and so on. + */ +async function claims(userId, use, scope) { + debug(`claims: userId:${userId} use:${use} scope:${scope}`); + + const [error, user] = await safe(users.get(userId)); + if (error) return { error: 'user not found' }; + + const displayName = user.displayName || user.username || ''; // displayName can be empty and username can be null + const nameParts = displayName.split(' '); + const firstName = nameParts[0]; + const lastName = nameParts.length > 1 ? nameParts[nameParts.length - 1] : ''; // choose last part, if it exists + + return { + sub: userId, // it is essential to always return a sub claim + email: user.email, + email_verified: true, + family_name: lastName, + given_name: firstName, + locale: 'en-US', + name: user.displayName, + preferred_username: user.username, + }; +} + async function getProvider(routePrefix) { assert.strictEqual(typeof routePrefix, 'string'); @@ -442,11 +421,11 @@ async function getProvider(routePrefix) { const configuration = { // use the one from Account class I guess? async findAccount(ctx, id) { - debug(`findAccount ctx:${ctx} id:${id}`); + debug(`findAccount id:${id}`, ctx); return { accountId: id, - async claims(use, scope) { return { sub: id }; }, + async claims(use, scope) { return await claims(id, use, scope); }, }; }, adapter: CloudronAdapter,