Add openid connect plugin
This commit is contained in:
		
							
								
								
									
										3
									
								
								peertube-plugin-auth-openid-connect/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								peertube-plugin-auth-openid-connect/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | # OpenID Connect auth plugin for PeerTube | ||||||
|  |  | ||||||
|  | Add OpenID Connect support to login form in PeerTube. | ||||||
							
								
								
									
										280
									
								
								peertube-plugin-auth-openid-connect/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								peertube-plugin-auth-openid-connect/main.js
									
									
									
									
									
										Normal file
									
								
							| @ -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) | ||||||
|  |     }) | ||||||
|  |   }) | ||||||
|  | } | ||||||
							
								
								
									
										376
									
								
								peertube-plugin-auth-openid-connect/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										376
									
								
								peertube-plugin-auth-openid-connect/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @ -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==" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								peertube-plugin-auth-openid-connect/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								peertube-plugin-auth-openid-connect/package.json
									
									
									
									
									
										Normal file
									
								
							| @ -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" | ||||||
|  |   } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user