2023-03-21 13:54:40 +01:00
'use strict' ;
exports = module . exports = {
2023-03-24 20:08:17 +01:00
clients : {
get ,
list ,
add ,
update ,
del
} ,
destroyUserSession
2023-03-21 13:54:40 +01:00
} ;
const assert = require ( 'assert' ) ,
BoxError = require ( '../boxerror.js' ) ,
oidc = require ( '../oidc.js' ) ,
HttpError = require ( 'connect-lastmile' ) . HttpError ,
HttpSuccess = require ( 'connect-lastmile' ) . HttpSuccess ,
safe = require ( 'safetydance' ) ;
async function add ( req , res , next ) {
assert . strictEqual ( typeof req . body , 'object' ) ;
if ( typeof req . body . id !== 'string' || ! req . body . id ) return next ( new HttpError ( 400 , 'id must be non-empty string' ) ) ;
2023-03-23 09:27:40 +01:00
if ( typeof req . body . name !== 'string' || ! req . body . name ) return next ( new HttpError ( 400 , 'name must be non-empty string' ) ) ;
2023-03-21 13:54:40 +01:00
if ( typeof req . body . secret !== 'string' || ! req . body . secret ) return next ( new HttpError ( 400 , 'secret must be non-empty string' ) ) ;
if ( typeof req . body . loginRedirectUri !== 'string' || ! req . body . loginRedirectUri ) return next ( new HttpError ( 400 , 'loginRedirectUri must be non-empty string' ) ) ;
2023-04-04 15:38:45 +02:00
if ( req . body . tokenSignatureAlgorithm !== 'EdDSA' && req . body . tokenSignatureAlgorithm !== 'RS256' ) return next ( new HttpError ( 400 , 'tokenSignatureAlgorithm must be either EdDSA or RS256' ) ) ;
2023-03-21 13:54:40 +01:00
if ( 'logoutRedirectUri' in req . body && ( typeof req . body . logoutRedirectUri !== 'string' || ! req . body . logoutRedirectUri ) ) return next ( new HttpError ( 400 , 'logoutRedirectUri must be non-empty string if provided' ) ) ;
2023-03-23 09:27:40 +01:00
const data = {
secret : req . body . secret ,
name : req . body . name ,
appId : '' , // always empty for custom clients
2023-04-04 15:38:45 +02:00
tokenSignatureAlgorithm : req . body . tokenSignatureAlgorithm ,
2023-03-23 09:27:40 +01:00
loginRedirectUri : req . body . loginRedirectUri ,
logoutRedirectUri : req . body . logoutRedirectUri || ''
} ;
const [ error ] = await safe ( oidc . clients . add ( req . body . id , data ) ) ;
2023-03-21 13:54:40 +01:00
if ( error ) return next ( BoxError . toHttpError ( error ) ) ;
next ( new HttpSuccess ( 201 , { } ) ) ;
}
async function get ( req , res , next ) {
assert . strictEqual ( typeof req . params . clientId , 'string' ) ;
const [ error , client ] = await safe ( oidc . clients . get ( req . params . clientId ) ) ;
if ( error ) return next ( BoxError . toHttpError ( error ) ) ;
2023-03-21 14:46:09 +01:00
if ( ! client ) return next ( new HttpError ( 404 , 'OpenID connect client not found' ) ) ;
2023-03-21 13:54:40 +01:00
next ( new HttpSuccess ( 200 , client ) ) ;
}
async function update ( req , res , next ) {
assert . strictEqual ( typeof req . params . clientId , 'string' ) ;
assert . strictEqual ( typeof req . body , 'object' ) ;
2023-03-23 09:27:40 +01:00
if ( typeof req . body . name !== 'string' || ! req . body . name ) return next ( new HttpError ( 400 , 'name must be non-empty string' ) ) ;
2023-03-21 13:54:40 +01:00
if ( typeof req . body . secret !== 'string' || ! req . body . secret ) return next ( new HttpError ( 400 , 'secret must be non-empty string' ) ) ;
if ( typeof req . body . loginRedirectUri !== 'string' || ! req . body . loginRedirectUri ) return next ( new HttpError ( 400 , 'loginRedirectUri must be non-empty string' ) ) ;
2023-04-04 15:38:45 +02:00
if ( req . body . tokenSignatureAlgorithm !== 'EdDSA' && req . body . tokenSignatureAlgorithm !== 'RS256' ) return next ( new HttpError ( 400 , 'tokenSignatureAlgorithm must be either EdDSA or RS256' ) ) ;
2023-03-21 13:54:40 +01:00
if ( 'logoutRedirectUri' in req . body && ( typeof req . body . logoutRedirectUri !== 'string' || ! req . body . logoutRedirectUri ) ) return next ( new HttpError ( 400 , 'logoutRedirectUri must be non-empty string if provided' ) ) ;
2023-03-23 09:27:40 +01:00
const data = {
secret : req . body . secret ,
name : req . body . name ,
appId : '' , // always empty for custom clients
2023-04-04 15:38:45 +02:00
tokenSignatureAlgorithm : req . body . tokenSignatureAlgorithm ,
2023-03-23 09:27:40 +01:00
loginRedirectUri : req . body . loginRedirectUri ,
logoutRedirectUri : req . body . logoutRedirectUri || ''
} ;
const [ error ] = await safe ( oidc . clients . update ( req . params . clientId , data ) ) ;
2023-03-21 13:54:40 +01:00
if ( error ) return next ( BoxError . toHttpError ( error ) ) ;
2023-03-21 19:09:44 +01:00
next ( new HttpSuccess ( 201 , { } ) ) ;
2023-03-21 13:54:40 +01:00
}
async function list ( req , res , next ) {
const [ error , result ] = await safe ( oidc . clients . list ( ) ) ;
if ( error ) return next ( BoxError . toHttpError ( error ) ) ;
next ( new HttpSuccess ( 200 , { clients : result } ) ) ;
}
2023-03-24 20:08:17 +01:00
async function del ( req , res , next ) {
2023-03-21 13:54:40 +01:00
assert . strictEqual ( typeof req . params . clientId , 'string' ) ;
const [ error ] = await safe ( oidc . clients . del ( req . params . clientId ) ) ;
if ( error ) return next ( BoxError . toHttpError ( error ) ) ;
next ( new HttpSuccess ( 204 ) ) ;
}
2023-03-24 20:08:17 +01:00
async function destroyUserSession ( req , res , next ) {
assert . strictEqual ( typeof req . user , 'object' ) ;
const [ error ] = await safe ( oidc . revokeByUserId ( req . user . id ) ) ;
if ( error ) return next ( BoxError . toHttpError ( error ) ) ;
next ( new HttpSuccess ( 204 ) ) ;
}