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