diff --git a/index.js b/index.js index 69fc3f8..79d62fc 100644 --- a/index.js +++ b/index.js @@ -5,6 +5,7 @@ const process = require('node:process'); const AppleStrategy = require('@nicokaiser/passport-apple').Strategy; const GitHubStrategy = require('passport-github2').Strategy; const GoogleStrategy = require('passport-google-oauth20'); +const UbuntuStrategy = require('passport-ubuntu').Strategy; const OtpStrategy = require('@ladjs/passport-otp-strategy').Strategy; const WebAuthnStrategy = require('@forwardemail/passport-fido2-webauthn'); const _ = require('lodash'); @@ -36,6 +37,9 @@ const PASSPORT_FIELDS = { githubProfileID: 'github_profile_id', githubAccessToken: 'github_access_token', githubRefreshToken: 'github_refresh_token', + // ubuntu + ubuntuProfileID: 'ubuntu_profile_id', + ubuntuUsername: 'ubuntu_username', // otp otpToken: 'otp_token', otpEnabled: 'otp_enabled' @@ -71,7 +75,8 @@ class Passport extends KoaPassport { google: boolean(process.env.AUTH_GOOGLE_ENABLED), github: boolean(process.env.AUTH_GITHUB_ENABLED), otp: boolean(process.env.AUTH_OTP_ENABLED), - webauthn: boolean(process.env.AUTH_WEBAUTHN_ENABLED) + webauthn: boolean(process.env.AUTH_WEBAUTHN_ENABLED), + ubuntu: boolean(process.env.AUTH_UBUNTU_ENABLED) }, strategies: { apple: { @@ -114,6 +119,11 @@ class Passport extends KoaPassport { store // // passReqToCallback: true + }, + ubuntu: { + returnURL: process.env.UBUNTU_CALLBACK_URL, + realm: process.env.UBUNTU_REALM, + stateless: true } }, fields: PASSPORT_FIELDS, @@ -142,6 +152,19 @@ class Passport extends KoaPassport { this.use(Users.createStrategy()); } + // + // ubuntu (openid) + // + // + // + // + this.use( + new UbuntuStrategy( + this.config.strategies.ubuntu, + this.loginOrCreateProfile(Users, 'ubuntu') + ) + ); + // apple if (this.config.providers.apple) this.use( @@ -267,6 +290,18 @@ class Passport extends KoaPassport { loginOrCreateProfile(Users, provider) { return (accessToken, refreshToken, profile, done) => { + if (provider === 'ubuntu') { + profile = refreshToken; + if (_.isObject(profile) && isSANB(profile.claimedIdentifier)) + profile.id = profile.claimedIdentifier; + if (_.isArray(profile.fullname) && isSANB(profile.fullname[0])) + profile.displayName = profile.fullname[0]; + accessToken = null; + refreshToken = null; + if (!_.isArray(profile.nickname) || !isSANB(profile.nickname[0])) + return done(new Error(this.config.phrases.INVALID_PROFILE_ID)); + } + if (!_.isObject(profile)) return done(new Error(this.config.phrases.INVALID_PROFILE_RESPONSE)); @@ -382,6 +417,14 @@ class Passport extends KoaPassport { user[this.config.fields[key]] = profile[key]; } + // ubuntu + if ( + provider === 'ubuntu' && + _.isArray(profile.nickname) && + isSANB(profile.nickname[0]) + ) + user[this.config.fields.ubuntuUsername] = profile.nickname[0]; + // // google photo // (we don't want to override values if they were already set though) @@ -434,6 +477,17 @@ class Passport extends KoaPassport { user.email = email; } + // if ubuntu then update nickname if not set already + if ( + provider === 'ubuntu' && + _.isArray(profile.nickname) && + isSANB(profile.nickname[0]) && + profile.nickname[0] !== user[this.config.fields.ubuntuUsername] + ) { + save = true; + user[this.config.fields.ubuntuUsername] = profile.nickname[0]; + } + // update or set access token if ( isSANB(accessToken) && diff --git a/package.json b/package.json index 9ad0d8f..4f7a846 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "lodash": "^4.17.21", "passport-github2": "^0.1.12", "passport-google-oauth20": "^2.0.0", + "passport-ubuntu": "^0.2.0", "validator": "^13.11.0" }, "devDependencies": {