From abcface9b5e64fc4617c82c66a8911ed94f58d70 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 30 Apr 2020 14:16:20 +0200 Subject: [PATCH] Add openid connect plugin --- peertube-plugin-auth-openid-connect/README.md | 3 + peertube-plugin-auth-openid-connect/main.js | 280 +++++++++++++ .../package-lock.json | 376 ++++++++++++++++++ .../package.json | 24 ++ 4 files changed, 683 insertions(+) create mode 100644 peertube-plugin-auth-openid-connect/README.md create mode 100644 peertube-plugin-auth-openid-connect/main.js create mode 100644 peertube-plugin-auth-openid-connect/package-lock.json create mode 100644 peertube-plugin-auth-openid-connect/package.json diff --git a/peertube-plugin-auth-openid-connect/README.md b/peertube-plugin-auth-openid-connect/README.md new file mode 100644 index 0000000..1e115c6 --- /dev/null +++ b/peertube-plugin-auth-openid-connect/README.md @@ -0,0 +1,3 @@ +# OpenID Connect auth plugin for PeerTube + +Add OpenID Connect support to login form in PeerTube. diff --git a/peertube-plugin-auth-openid-connect/main.js b/peertube-plugin-auth-openid-connect/main.js new file mode 100644 index 0000000..454ba96 --- /dev/null +++ b/peertube-plugin-auth-openid-connect/main.js @@ -0,0 +1,280 @@ +const openidModule = require('openid-client') +const crypto = require('crypto') + +const store = { + client: null, + userAuthenticated: null, + secretKey: null, + redirectUrl: null +} + +const encryptionOptions = { + algorithm: 'aes256', + inputEncoding: 'utf8', + outputEncoding: 'hex' +} + +const cookieName = 'plugin-auth-openid-code-verifier' + +async function register ({ + registerExternalAuth, + unregisterExternalAuth, + registerSetting, + settingsManager, + peertubeHelpers, + getRouter +}) { + const { logger } = peertubeHelpers + + registerSetting({ + name: 'discover-url', + label: 'Discover URL', + type: 'input', + private: true + }) + + registerSetting({ + name: 'client-id', + label: 'Client ID', + type: 'input', + private: true + }) + + registerSetting({ + name: 'client-secret', + label: 'Client secret', + type: 'input', + private: true + }) + + registerSetting({ + name: 'username-property', + label: 'Username property', + type: 'input', + private: true, + default: 'preferred_username' + }) + + registerSetting({ + name: 'mail-property', + label: 'Email property', + type: 'input', + private: true, + default: 'email' + }) + + registerSetting({ + name: 'display-name-property', + label: 'Display name property', + type: 'input', + private: true + }) + + registerSetting({ + name: 'role-property', + label: 'Role property', + type: 'input', + private: true + }) + + const router = getRouter() + router.use('/id-token-cb', (req, res) => handleCb(peertubeHelpers, settingsManager, req, res)) + + store.redirectUrl = peertubeHelpers.config.getWebserverUrl() + '/plugins/auth-openid-connect/router/id-token-cb' + + const secretKeyBuf = await getRandomBytes(16) + store.secretKey = secretKeyBuf.toString('hex') + + await loadSettingsAndCreateClient(registerExternalAuth, unregisterExternalAuth, peertubeHelpers, settingsManager) + + settingsManager.onSettingsChange(() => { + loadSettingsAndCreateClient(registerExternalAuth, unregisterExternalAuth, peertubeHelpers, settingsManager) + .catch(err => logger.error('Cannot load settings and create client after settings changes.', { err })) + }) +} + +async function unregister () { + return +} + +module.exports = { + register, + unregister +} + +// ############################################################################ + +async function loadSettingsAndCreateClient (registerExternalAuth, unregisterExternalAuth, peertubeHelpers, settingsManager) { + const { logger, config } = peertubeHelpers + + if (store.client) { + unregisterExternalAuth('openid') + } + + store.client = null + store.userAuthenticated = null + + const settings = await settingsManager.getSettings([ + 'discover-url', + 'client-id', + 'client-secret' + ]) + + if (!settings['discover-url']) { + logger.info('Do not register external openid auth because discover URL is not set.') + return + } + + if (!settings['client-id']) { + logger.info('Do not register external openid auth because client ID is not set.') + return + } + + const discoverUrl = settings['discover-url'] + const issuer = await openidModule.Issuer.discover(discoverUrl) + + logger.debug('Discovered issuer %s.', discoverUrl) + + const clientOptions = { + client_id: settings['client-id'], + redirect_uris: [ store.redirectUrl ], + response_types: [ 'code' ] + } + + if (settings['client-secret']) { + clientOptions.client_secret = settings['client-secret'] + } else { + clientOptions.token_endpoint_auth_method = 'none' + } + + store.client = new issuer.Client(clientOptions) + + // We already registered this external auth + if (store.userAuthenticated) return + + const webserverUrl = config.getWebserverUrl() + + const result = registerExternalAuth({ + authName: 'openid-connect', + authDisplayName: () => 'OpenID Connect', + onAuthRequest: async (req, res) => { + try { + const codeVerifier = openidModule.generators.codeVerifier() + const codeChallenge = openidModule.generators.codeChallenge(codeVerifier) + + const redirectUrl = store.client.authorizationUrl({ + scope: 'openid email profile', + response_mode: 'form_post', + code_challenge: codeChallenge, + code_challenge_method: 'S256' + }) + + const encryptedCodeVerifier = await encrypt(codeVerifier) + res.cookie(cookieName, encryptedCodeVerifier, { + secure: webserverUrl.startsWith('https://'), + httpOnly: true, + sameSite: 'none', + maxAge: 1000 * 60 * 10 // 10 minutes + }) + + return res.redirect(redirectUrl) + } catch (err) { + logger.error('Cannot handle auth request.', { err }) + } + } + }) + + store.userAuthenticated = result.userAuthenticated +} + +async function handleCb (peertubeHelpers, settingsManager, req, res) { + const { logger } = peertubeHelpers + + if (!store.userAuthenticated) { + logger.info('Received callback but cannot userAuthenticated function does not exist.') + return res.sendStatus(400) + } + + const encryptedCodeVerifier = req.cookies[cookieName] + if (!encryptedCodeVerifier) { + logger.error('Received callback but code verifier not found in request cookie.') + return res.sendStatus(400) + } + + try { + const codeVerifier = await decrypt(encryptedCodeVerifier) + + const params = store.client.callbackParams(req) + const tokenSet = await store.client.callback(store.redirectUrl, params, { code_verifier: codeVerifier }) + + const accessToken = tokenSet.access_token + const userInfo = await store.client.userinfo(accessToken) + + const settings = await settingsManager.getSettings([ + 'mail-property', + 'username-property', + 'display-name-property', + 'role-property' + ]) + + logger.debug('Got userinfo from openid auth.', { userInfo, settings }) + + let role + if (settings['role-property']) { + role = parseInt('' + userInfo[settings['role-property']], 10) + } + + let displayName + if (settings['display-name-property']) { + displayName = userInfo[settings['display-name-property']] + } + + let username = userInfo[settings['username-property']] || '' + username = username.replace(/[^a-z0-9._]/g, '_') + + store.userAuthenticated({ + res, + req, + username, + email: userInfo[settings['mail-property']], + displayName, + role + }) + } catch (err) { + logger.error('Error in handle callback.', { err }) + res.sendStatus(400) + } +} + +async function encrypt (data) { + const { algorithm, inputEncoding, outputEncoding } = encryptionOptions + + const iv = await getRandomBytes(16) + + const cipher = crypto.createCipheriv(algorithm, store.secretKey, iv) + let encrypted = cipher.update(data, inputEncoding, outputEncoding) + encrypted += cipher.final(outputEncoding) + + return iv.toString(outputEncoding) + ':' + encrypted +} + +async function decrypt (data) { + const { algorithm, inputEncoding, outputEncoding } = encryptionOptions + + const encryptedArray = data.split(':') + const iv = Buffer.from(encryptedArray[0], outputEncoding) + const encrypted = Buffer.from(encryptedArray[1], outputEncoding) + const decipher = crypto.createDecipheriv(algorithm, store.secretKey, iv) + + return decipher.update(encrypted, outputEncoding, inputEncoding) + decipher.final(inputEncoding) +} + +function getRandomBytes (size) { + return new Promise((res, rej) => { + crypto.randomBytes(size, (err, buf) => { + if (err) return rej(err) + + return res(buf) + }) + }) +} diff --git a/peertube-plugin-auth-openid-connect/package-lock.json b/peertube-plugin-auth-openid-connect/package-lock.json new file mode 100644 index 0000000..888d972 --- /dev/null +++ b/peertube-plugin-auth-openid-connect/package-lock.json @@ -0,0 +1,376 @@ +{ + "name": "peertube-plugin-auth-openid", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@panva/asn1.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", + "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==" + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@types/got": { + "version": "9.6.10", + "resolved": "https://registry.npmjs.org/@types/got/-/got-9.6.10.tgz", + "integrity": "sha512-owBY1cgHUIXjObzY+vs+J9Cpw0czvfksJX+qEkgxRojFutFq7n1tKoj6Ekg57DhvXMk0vGQ7FbinvS9I/1wxcg==", + "requires": { + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "@types/node": { + "version": "13.13.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.4.tgz", + "integrity": "sha512-x26ur3dSXgv5AwKS0lNfbjpCakGIduWU1DU91Zz58ONRWrIKGunmZBNv4P7N+e27sJkiGDsw/3fT4AtsqQBrBA==" + }, + "@types/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==" + }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + } + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "jose": { + "version": "1.26.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-1.26.1.tgz", + "integrity": "sha512-2WQu8SezuTI/1FqvzEJGNLiSojGyFwnZK562rwoz2yx02Ad8k0IQ37bt7UaF/oyQiyn7he4VFfQnOAB5EHHUVw==", + "requires": { + "@panva/asn1.js": "^1.0.0" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "requires": { + "json-buffer": "3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" + }, + "object-hash": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz", + "integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==" + }, + "oidc-token-hash": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.0.tgz", + "integrity": "sha512-8Yr4CZSv+Tn8ZkN3iN2i2w2G92mUKClp4z7EGUfdsERiYSbj7P4i/NHm72ft+aUdsiFx9UdIPSTwbyzQ6C4URg==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "openid-client": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-3.15.0.tgz", + "integrity": "sha512-Xuvn0q1gQPcfkDYsEunrCiiMfy+ZZFjYMWxp5bkjiuj4BxhFbBo6RjlmCbhTLxdDnun0fp/qsC67bWL9AzP1BA==", + "requires": { + "@types/got": "^9.6.9", + "base64url": "^3.0.1", + "got": "^9.6.0", + "jose": "^1.25.2", + "lodash": "^4.17.15", + "lru-cache": "^5.1.1", + "make-error": "^1.3.6", + "object-hash": "^2.0.1", + "oidc-token-hash": "^5.0.0", + "p-any": "^3.0.0" + } + }, + "p-any": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-any/-/p-any-3.0.0.tgz", + "integrity": "sha512-5rqbqfsRWNb0sukt0awwgJMlaep+8jV45S15SKKB34z4UuzjcofIfnriCBhWjZP2jbVtjt9yRl7buB6RlKsu9w==", + "requires": { + "p-cancelable": "^2.0.0", + "p-some": "^5.0.0" + }, + "dependencies": { + "p-cancelable": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", + "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==" + } + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + }, + "p-some": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-some/-/p-some-5.0.0.tgz", + "integrity": "sha512-Js5XZxo6vHjB9NOYAzWDYAIyyiPvva0DWESAIWIK7uhSpGsyg5FwUPxipU/SOQx5x9EqhOh545d1jo6cVkitig==", + "requires": { + "aggregate-error": "^3.0.0", + "p-cancelable": "^2.0.0" + }, + "dependencies": { + "p-cancelable": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", + "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==" + } + } + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } + } +} diff --git a/peertube-plugin-auth-openid-connect/package.json b/peertube-plugin-auth-openid-connect/package.json new file mode 100644 index 0000000..3e32574 --- /dev/null +++ b/peertube-plugin-auth-openid-connect/package.json @@ -0,0 +1,24 @@ +{ + "name": "peertube-plugin-auth-openid-connect", + "version": "0.0.1", + "description": "Add OpenID connect support to login form in PeerTube.", + "engine": { + "peertube": ">=2.2.0" + }, + "keywords": [ + "peertube", + "plugin", + "auth" + ], + "homepage": "https://framagit.org/framasoft/peertube/official-plugins/tree/master/peertube-plugin-auth-openid-connect", + "author": "Chocobozzz", + "bugs": "https://framagit.org/framasoft/peertube/official-plugins/issues", + "library": "./main.js", + "staticDirs": {}, + "css": [], + "clientScripts": [], + "translations": {}, + "dependencies": { + "openid-client": "^3.15.0" + } +}