Finish server-side translations in controllers
This commit is contained in:
parent
86878efb52
commit
d2ae9c43e8
@ -25,12 +25,12 @@ class AppController extends Controller {
|
|||||||
|
|
||||||
if ( !application || !application.active )
|
if ( !application || !application.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('api:application_not_found'))
|
.message(req.T('api.application_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`app:${application.id}:view`) )
|
if ( !req.user.can(`app:${application.id}:view`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
return res.api(await application.to_api())
|
return res.api(await application.to_api())
|
||||||
@ -41,28 +41,28 @@ class AppController extends Controller {
|
|||||||
|
|
||||||
if ( !req.user.can('app:create') )
|
if ( !req.user.can('app:create') )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const required_fields = ['name', 'identifier']
|
const required_fields = ['name', 'identifier']
|
||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:missing_field')} ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the identifier is properly formatted
|
// Make sure the identifier is properly formatted
|
||||||
if ( !(new RegExp('^[a-zA-Z0-9_]*$')).test(req.body.identifier) )
|
if ( !(new RegExp('^[a-zA-Z0-9_]*$')).test(req.body.identifier) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:improper_field')} identifier ${req.T('api:alphanum_underscores')}`)
|
.message(`${req.T('api.improper_field')} identifier ${req.T('api.alphanum_underscores')}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Make sure the identifier is unique
|
// Make sure the identifier is unique
|
||||||
const existing_app = await Application.findOne({ identifier: req.body.identifier })
|
const existing_app = await Application.findOne({ identifier: req.body.identifier })
|
||||||
if ( existing_app )
|
if ( existing_app )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('api:application_already_exists'))
|
.message(req.T('api.application_already_exists'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const application = new Application({
|
const application = new Application({
|
||||||
@ -80,7 +80,7 @@ class AppController extends Controller {
|
|||||||
const client = await LDAPClient.findById(id)
|
const client = await LDAPClient.findById(id)
|
||||||
if ( !client || !client.active || !req.user.can(`ldap:client:${client.id}:view`) )
|
if ( !client || !client.active || !req.user.can(`ldap:client:${client.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:invalid_ldap_client_id')} ${id}`)
|
.message(`${req.T('api.invalid_ldap_client_id')} ${id}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const other_assoc_app = await Application.findOne({ ldap_client_ids: client.id })
|
const other_assoc_app = await Application.findOne({ ldap_client_ids: client.id })
|
||||||
@ -102,7 +102,7 @@ class AppController extends Controller {
|
|||||||
const client = await OAuthClient.findById(id)
|
const client = await OAuthClient.findById(id)
|
||||||
if ( !client || !client.active || !req.user.can(`oauth:client:${client.id}:view`) )
|
if ( !client || !client.active || !req.user.can(`oauth:client:${client.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:invalid_oauth_client_id')} ${id}`)
|
.message(`${req.T('api.invalid_oauth_client_id')} ${id}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const other_assoc_app = await Application.findOne({ oauth_client_ids: client.id })
|
const other_assoc_app = await Application.findOne({ oauth_client_ids: client.id })
|
||||||
@ -124,7 +124,7 @@ class AppController extends Controller {
|
|||||||
const provider = await ServiceProvider.findById(id)
|
const provider = await ServiceProvider.findById(id)
|
||||||
if ( !provider || !provider.active || !req.user.can(`saml:provider:${provider.id}:view`) )
|
if ( !provider || !provider.active || !req.user.can(`saml:provider:${provider.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:invalid_saml_service_provider_id')} ${id}`)
|
.message(`${req.T('api.invalid_saml_service_provider_id')} ${id}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const other_assoc_app = await Application.findOne({ saml_service_provider_ids: provider.id })
|
const other_assoc_app = await Application.findOne({ saml_service_provider_ids: provider.id })
|
||||||
@ -147,33 +147,33 @@ class AppController extends Controller {
|
|||||||
|
|
||||||
if ( !application || !application.active )
|
if ( !application || !application.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('api:application_not_found'))
|
.message(req.T('api.application_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`app:${application.id}:update`) )
|
if ( !req.user.can(`app:${application.id}:update`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const required_fields = ['name', 'identifier']
|
const required_fields = ['name', 'identifier']
|
||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:missing_field')} ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the identifier is properly formatted
|
// Make sure the identifier is properly formatted
|
||||||
if ( !(new RegExp('^[a-zA-Z0-9_]*$')).test(req.body.identifier) )
|
if ( !(new RegExp('^[a-zA-Z0-9_]*$')).test(req.body.identifier) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:improper_field')} identifier ${req.T('api:alphanum_underscores')}`)
|
.message(`${req.T('api.improper_field')} identifier ${req.T('api.alphanum_underscores')}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Make sure the identifier is unique
|
// Make sure the identifier is unique
|
||||||
const existing_app = await Application.findOne({ identifier: req.body.identifier })
|
const existing_app = await Application.findOne({ identifier: req.body.identifier })
|
||||||
if ( existing_app && existing_app.id !== application.id )
|
if ( existing_app && existing_app.id !== application.id )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('api:application_already_exists'))
|
.message(req.T('api.application_already_exists'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Verify LDAP client IDs
|
// Verify LDAP client IDs
|
||||||
@ -185,7 +185,7 @@ class AppController extends Controller {
|
|||||||
const client = await LDAPClient.findById(id)
|
const client = await LDAPClient.findById(id)
|
||||||
if ( !client || !client.active || !req.user.can(`ldap:client:${client.id}:view`) )
|
if ( !client || !client.active || !req.user.can(`ldap:client:${client.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:invalid_ldap_client_id')} ${id}`)
|
.message(`${req.T('api.invalid_ldap_client_id')} ${id}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const other_assoc_app = await Application.findOne({ ldap_client_ids: client.id })
|
const other_assoc_app = await Application.findOne({ ldap_client_ids: client.id })
|
||||||
@ -207,7 +207,7 @@ class AppController extends Controller {
|
|||||||
const client = await OAuthClient.findById(id)
|
const client = await OAuthClient.findById(id)
|
||||||
if ( !client || !client.active || !req.user.can(`oauth:client:${client.id}:view`) )
|
if ( !client || !client.active || !req.user.can(`oauth:client:${client.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:invalid_oauth_client_id')} ${id}`)
|
.message(`${req.T('api.invalid_oauth_client_id')} ${id}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const other_assoc_app = await Application.findOne({ oauth_client_ids: client.id })
|
const other_assoc_app = await Application.findOne({ oauth_client_ids: client.id })
|
||||||
@ -229,7 +229,7 @@ class AppController extends Controller {
|
|||||||
const provider = await ServiceProvider.findById(id)
|
const provider = await ServiceProvider.findById(id)
|
||||||
if ( !provider || !provider.active || !req.user.can(`saml:provider:${provider.id}:view`) )
|
if ( !provider || !provider.active || !req.user.can(`saml:provider:${provider.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:invalid_saml_service_provider_id')} ${id}`)
|
.message(`${req.T('api.invalid_saml_service_provider_id')} ${id}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const other_assoc_app = await Application.findOne({ saml_service_provider_ids: provider.id })
|
const other_assoc_app = await Application.findOne({ saml_service_provider_ids: provider.id })
|
||||||
@ -255,12 +255,12 @@ class AppController extends Controller {
|
|||||||
|
|
||||||
if ( !application || !application.active )
|
if ( !application || !application.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('api:application_not_found'))
|
.message(req.T('api.application_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`app:${application.id}:delete`) )
|
if ( !req.user.can(`app:${application.id}:delete`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
application.active = false
|
application.active = false
|
||||||
|
@ -20,7 +20,7 @@ class AuthController extends Controller {
|
|||||||
|
|
||||||
async get_traps(req, res, next) {
|
async get_traps(req, res, next) {
|
||||||
const trap_config = this.configs.get('traps')
|
const trap_config = this.configs.get('traps')
|
||||||
const data = [{ name: req.T('auth:none'), trap: '', redirect_to: '/' }]
|
const data = [{ name: req.T('auth.none'), trap: '', redirect_to: '/' }]
|
||||||
for ( const name in trap_config.types ) {
|
for ( const name in trap_config.types ) {
|
||||||
if ( !trap_config.types.hasOwnProperty(name) ) continue
|
if ( !trap_config.types.hasOwnProperty(name) ) continue
|
||||||
data.push({
|
data.push({
|
||||||
@ -44,18 +44,18 @@ class AuthController extends Controller {
|
|||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:missing_field')} ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !req.body.uid.match(/^([A-Z]|[a-z]|[0-9]|_|-|\.)+$/) )
|
if ( !req.body.uid.match(/^([A-Z]|[a-z]|[0-9]|_|-|\.)+$/) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:improper_field')} uid ${req.T('api:alphanum_underscores')}`)
|
.message(`${req.T('api.improper_field')} uid ${req.T('api.alphanum_underscores')}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !email_validator.validate(req.body.email) )
|
if ( !email_validator.validate(req.body.email) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:improper_field')} email`)
|
.message(`${req.T('api.improper_field')} email`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
for ( const field of unique_fields ) {
|
for ( const field of unique_fields ) {
|
||||||
@ -64,7 +64,7 @@ class AuthController extends Controller {
|
|||||||
const match_user = await User.findOne(params)
|
const match_user = await User.findOne(params)
|
||||||
if ( match_user )
|
if ( match_user )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('auth:user_exists_with_field')} ${field}`)
|
.message(`${req.T('auth.user_exists_with_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,12 +91,12 @@ class AuthController extends Controller {
|
|||||||
|| req.user.mfa_token.recovery_codes.length < 1
|
|| req.user.mfa_token.recovery_codes.length < 1
|
||||||
)
|
)
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('auth:no_mfa_or_recovery'))
|
.message(req.T('auth.no_mfa_or_recovery'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.body.code )
|
if ( !req.body.code )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:missing_field')} code`)
|
.message(`${req.T('api.missing_field')} code`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const success = await req.user.mfa_token.attempt_recovery(req.body.code)
|
const success = await req.user.mfa_token.attempt_recovery(req.body.code)
|
||||||
@ -176,7 +176,7 @@ class AuthController extends Controller {
|
|||||||
|
|
||||||
if ( !group || !group.active )
|
if ( !group || !group.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('api:group_not_found'))
|
.message(req.T('api.group_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`auth:group:${group.id}:view`) )
|
if ( !req.user.can(`auth:group:${group.id}:view`) )
|
||||||
@ -196,12 +196,12 @@ class AuthController extends Controller {
|
|||||||
|
|
||||||
if ( !user )
|
if ( !user )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('api:user_not_found'))
|
.message(req.T('api.user_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`auth:user:${user.id}:view`) )
|
if ( !req.user.can(`auth:user:${user.id}:view`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
return res.api(await user.to_api())
|
return res.api(await user.to_api())
|
||||||
@ -210,12 +210,12 @@ class AuthController extends Controller {
|
|||||||
async create_group(req, res, next) {
|
async create_group(req, res, next) {
|
||||||
if ( !req.user.can(`auth:group:create`) )
|
if ( !req.user.can(`auth:group:create`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.body.name )
|
if ( !req.body.name )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:missing_field')} name`)
|
.message(`${req.T('api.missing_field')} name`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const Group = this.models.get('auth:Group')
|
const Group = this.models.get('auth:Group')
|
||||||
@ -224,7 +224,7 @@ class AuthController extends Controller {
|
|||||||
const existing_group = await Group.findOne({ name: req.body.name })
|
const existing_group = await Group.findOne({ name: req.body.name })
|
||||||
if ( existing_group )
|
if ( existing_group )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('api:group_already_exists'))
|
.message(req.T('api.group_already_exists'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const group = new Group({ name: req.body.name })
|
const group = new Group({ name: req.body.name })
|
||||||
@ -238,7 +238,7 @@ class AuthController extends Controller {
|
|||||||
const user = await User.findById(user_id)
|
const user = await User.findById(user_id)
|
||||||
if ( !user )
|
if ( !user )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} user_id.`)
|
.message(`${req.T('common.invalid')} user_id.`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,14 +252,14 @@ class AuthController extends Controller {
|
|||||||
async create_user(req, res, next) {
|
async create_user(req, res, next) {
|
||||||
if ( !req.user.can('auth:user:create') )
|
if ( !req.user.can('auth:user:create') )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const required_fields = ['uid', 'first_name', 'last_name', 'email', 'password']
|
const required_fields = ['uid', 'first_name', 'last_name', 'email', 'password']
|
||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:missing_field')} ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ class AuthController extends Controller {
|
|||||||
const existing_user = await User.findOne(filter)
|
const existing_user = await User.findOne(filter)
|
||||||
if ( existing_user )
|
if ( existing_user )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('auth:user_exists_with_field')} ${field}`)
|
.message(`${req.T('auth.user_exists_with_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ class AuthController extends Controller {
|
|||||||
const result = zxcvbn(req.body.password)
|
const result = zxcvbn(req.body.password)
|
||||||
if ( result.score < min_score )
|
if ( result.score < min_score )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('auth:password_complexity_fail').replace('MIN_SCORE', min_score))
|
.message(req.T('auth.password_complexity_fail').replace('MIN_SCORE', min_score))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const user = new User({
|
const user = new User({
|
||||||
@ -297,7 +297,7 @@ class AuthController extends Controller {
|
|||||||
if ( req.body.trap ) {
|
if ( req.body.trap ) {
|
||||||
if ( !req.trap.trap_exists(req.body.trap) )
|
if ( !req.trap.trap_exists(req.body.trap) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('auth:invalid_trap'))
|
.message(req.T('auth.invalid_trap'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
user.trap = req.body.trap
|
user.trap = req.body.trap
|
||||||
@ -315,24 +315,24 @@ class AuthController extends Controller {
|
|||||||
const group = await Group.findById(req.params.id)
|
const group = await Group.findById(req.params.id)
|
||||||
if ( !group )
|
if ( !group )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('api:group_not_found'))
|
.message(req.T('api.group_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`auth:group:${group.id}:update`) )
|
if ( !req.user.can(`auth:group:${group.id}:update`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.body.name )
|
if ( !req.body.name )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:missing_field')} name`)
|
.message(`${req.T('api.missing_field')} name`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Make sure the group name is unique
|
// Make sure the group name is unique
|
||||||
const existing_group = await Group.findOne({ name: req.body.name })
|
const existing_group = await Group.findOne({ name: req.body.name })
|
||||||
if ( existing_group && existing_group.id !== group.id )
|
if ( existing_group && existing_group.id !== group.id )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('api:group_already_exists'))
|
.message(req.T('api.group_already_exists'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Validate user_ids
|
// Validate user_ids
|
||||||
@ -343,7 +343,7 @@ class AuthController extends Controller {
|
|||||||
const user = await User.findById(user_id)
|
const user = await User.findById(user_id)
|
||||||
if ( !user )
|
if ( !user )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} user_id.`)
|
.message(`${req.T('common.invalid')} user_id.`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,19 +363,19 @@ class AuthController extends Controller {
|
|||||||
|
|
||||||
if ( !user )
|
if ( !user )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('api:user_not_found'))
|
.message(req.T('api.user_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`auth:user:${user.id}:update`) )
|
if ( !req.user.can(`auth:user:${user.id}:update`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const required_fields = ['uid', 'first_name', 'last_name', 'email']
|
const required_fields = ['uid', 'first_name', 'last_name', 'email']
|
||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:missing_field')} ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,7 +387,7 @@ class AuthController extends Controller {
|
|||||||
const existing_user = await User.findOne(filter)
|
const existing_user = await User.findOne(filter)
|
||||||
if ( existing_user && existing_user.id !== user.id )
|
if ( existing_user && existing_user.id !== user.id )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('auth:user_exists_with_field')} ${field}`)
|
.message(`${req.T('auth.user_exists_with_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +397,7 @@ class AuthController extends Controller {
|
|||||||
const result = zxcvbn(req.body.password)
|
const result = zxcvbn(req.body.password)
|
||||||
if (result.score < min_score)
|
if (result.score < min_score)
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('auth:password_complexity_fail').replace('MIN_SCORE', min_score))
|
.message(req.T('auth.password_complexity_fail').replace('MIN_SCORE', min_score))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
await user.reset_password(req.body.password, 'api')
|
await user.reset_password(req.body.password, 'api')
|
||||||
@ -416,7 +416,7 @@ class AuthController extends Controller {
|
|||||||
if ( req.body.trap ) {
|
if ( req.body.trap ) {
|
||||||
if ( !req.trap.trap_exists(req.body.trap) )
|
if ( !req.trap.trap_exists(req.body.trap) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('auth:invalid_trap'))
|
.message(req.T('auth.invalid_trap'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
user.trap = req.body.trap
|
user.trap = req.body.trap
|
||||||
@ -433,12 +433,12 @@ class AuthController extends Controller {
|
|||||||
|
|
||||||
if ( !group )
|
if ( !group )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('api:group_not_found'))
|
.message(req.T('api.group_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`auth:group:${group.id}:delete`) )
|
if ( !req.user.can(`auth:group:${group.id}:delete`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
group.active = false
|
group.active = false
|
||||||
@ -452,12 +452,12 @@ class AuthController extends Controller {
|
|||||||
|
|
||||||
if ( !user )
|
if ( !user )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('api:user_not_found'))
|
.message(req.T('api.user_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`auth:user:${user.id}:delete`) )
|
if ( !req.user.can(`auth:user:${user.id}:delete`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// check if the user is an LDAP client. if so, delete the client
|
// check if the user is an LDAP client. if so, delete the client
|
||||||
@ -493,7 +493,7 @@ class AuthController extends Controller {
|
|||||||
|
|
||||||
if ( !req.body.username && !req.body.email )
|
if ( !req.body.username && !req.body.email )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:provide_one')} username, email`)
|
.message(`${req.T('api.provide_one')} username, email`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const data = {}
|
const data = {}
|
||||||
@ -529,7 +529,7 @@ class AuthController extends Controller {
|
|||||||
const errors = await flitter.validate_login(req.body)
|
const errors = await flitter.validate_login(req.body)
|
||||||
if ( errors && errors.length > 0 )
|
if ( errors && errors.length > 0 )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('auth:unable_to_complete'))
|
.message(req.T('auth.unable_to_complete'))
|
||||||
.api({ errors })
|
.api({ errors })
|
||||||
|
|
||||||
const login_args = await flitter.get_login_args(req.body)
|
const login_args = await flitter.get_login_args(req.body)
|
||||||
@ -537,9 +537,9 @@ class AuthController extends Controller {
|
|||||||
|
|
||||||
if ( !user )
|
if ( !user )
|
||||||
return res.status(200)
|
return res.status(200)
|
||||||
.message(req.T('auth:invalid_un_or_pw'))
|
.message(req.T('auth.invalid_un_or_pw'))
|
||||||
.api({
|
.api({
|
||||||
message: req.T('auth:invalid_un_or_pw'),
|
message: req.T('auth.invalid_un_or_pw'),
|
||||||
success: false,
|
success: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -549,9 +549,9 @@ class AuthController extends Controller {
|
|||||||
const client = await Client.findOne({ user_id: user.id })
|
const client = await Client.findOne({ user_id: user.id })
|
||||||
if ( client )
|
if ( client )
|
||||||
return res.status(200)
|
return res.status(200)
|
||||||
.message(req.T('auth:invalid_un_or_pw'))
|
.message(req.T('auth.invalid_un_or_pw'))
|
||||||
.api({
|
.api({
|
||||||
message: req.T('auth:invalid_un_or_pw'),
|
message: req.T('auth.invalid_un_or_pw'),
|
||||||
success: false,
|
success: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -585,7 +585,7 @@ class AuthController extends Controller {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('auth:unable_to_grant_trust'))
|
.message(req.T('auth.unable_to_grant_trust'))
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -600,7 +600,7 @@ class AuthController extends Controller {
|
|||||||
async get_mfa_recovery(req, res, next) {
|
async get_mfa_recovery(req, res, next) {
|
||||||
if ( !req.user.mfa_enabled )
|
if ( !req.user.mfa_enabled )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('auth:no_mfa'))
|
.message(req.T('auth.no_mfa'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const token = req.user.mfa_token
|
const token = req.user.mfa_token
|
||||||
@ -617,7 +617,7 @@ class AuthController extends Controller {
|
|||||||
async generate_mfa_recovery(req, res, next) {
|
async generate_mfa_recovery(req, res, next) {
|
||||||
if ( !req.user.mfa_enabled )
|
if ( !req.user.mfa_enabled )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('auth:no_mfa'))
|
.message(req.T('auth.no_mfa'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const token = req.user.mfa_token
|
const token = req.user.mfa_token
|
||||||
@ -631,7 +631,7 @@ class AuthController extends Controller {
|
|||||||
async generate_mfa_key(req, res, next) {
|
async generate_mfa_key(req, res, next) {
|
||||||
if ( req.user.mfa_enabled )
|
if ( req.user.mfa_enabled )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('auth:already_has_mfa'))
|
.message(req.T('auth.already_has_mfa'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const MFAToken = this.models.get('auth:MFAToken')
|
const MFAToken = this.models.get('auth:MFAToken')
|
||||||
@ -654,7 +654,7 @@ class AuthController extends Controller {
|
|||||||
async attempt_mfa(req, res, next) {
|
async attempt_mfa(req, res, next) {
|
||||||
if ( !req.user.mfa_token )
|
if ( !req.user.mfa_token )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('auth:no_mfa'))
|
.message(req.T('auth.no_mfa'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const code = req.body.verify_code
|
const code = req.body.verify_code
|
||||||
@ -682,7 +682,7 @@ class AuthController extends Controller {
|
|||||||
async enable_mfa(req, res, next) {
|
async enable_mfa(req, res, next) {
|
||||||
if ( !req.user.mfa_token )
|
if ( !req.user.mfa_token )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('auth:no_mfa'))
|
.message(req.T('auth.no_mfa'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
req.user.mfa_enabled = true
|
req.user.mfa_enabled = true
|
||||||
@ -700,7 +700,7 @@ class AuthController extends Controller {
|
|||||||
async disable_mfa(req, res, next) {
|
async disable_mfa(req, res, next) {
|
||||||
if ( !req.user.mfa_enabled )
|
if ( !req.user.mfa_enabled )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(req.T('auth:no_mfa'))
|
.message(req.T('auth.no_mfa'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
req.user.mfa_enabled = false
|
req.user.mfa_enabled = false
|
||||||
|
@ -10,7 +10,7 @@ class IAMController extends Controller {
|
|||||||
|
|
||||||
if ( !req.body.entity_id && !req.body.target_id )
|
if ( !req.body.entity_id && !req.body.target_id )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:missing_field', true)} entity_id, target_id`)
|
.message(`${req.T('api.missing_field', true)} entity_id, target_id`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
return res.api(await Policy.check_entity_access(req.body.entity_id, req.body.target_id))
|
return res.api(await Policy.check_entity_access(req.body.entity_id, req.body.target_id))
|
||||||
@ -22,7 +22,7 @@ class IAMController extends Controller {
|
|||||||
|
|
||||||
if ( !req.body.target_id )
|
if ( !req.body.target_id )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:missing_field')} target_id`)
|
.message(`${req.T('api.missing_field')} target_id`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
let user = req.user
|
let user = req.user
|
||||||
@ -31,12 +31,12 @@ class IAMController extends Controller {
|
|||||||
|
|
||||||
if ( !user )
|
if ( !user )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('api:user_not_found'))
|
.message(req.T('api.user_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`auth:user:${user.id}:view`) )
|
if ( !req.user.can(`auth:user:${user.id}:view`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
return res.api(await Policy.check_user_access(user, req.body.target_id))
|
return res.api(await Policy.check_user_access(user, req.body.target_id))
|
||||||
@ -62,12 +62,12 @@ class IAMController extends Controller {
|
|||||||
|
|
||||||
if ( !policy )
|
if ( !policy )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('iam:policy_not_found'))
|
.message(req.T('iam.policy_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`iam:policy:${policy.id}:view`) )
|
if ( !req.user.can(`iam:policy:${policy.id}:view`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
return res.api(await policy.to_api())
|
return res.api(await policy.to_api())
|
||||||
@ -80,13 +80,13 @@ class IAMController extends Controller {
|
|||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:missing_field')} ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !['user', 'group'].includes(req.body.entity_type) )
|
if ( !['user', 'group'].includes(req.body.entity_type) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('iam:invalid_entity')} user, group`)
|
.message(`${req.T('iam.invalid_entity')} user, group`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Make sure the entity_id is valid
|
// Make sure the entity_id is valid
|
||||||
@ -95,25 +95,25 @@ class IAMController extends Controller {
|
|||||||
const user = await User.findById(req.body.entity_id)
|
const user = await User.findById(req.body.entity_id)
|
||||||
if ( !user || !req.user.can(`auth:user:${user.id}:view`) )
|
if ( !user || !req.user.can(`auth:user:${user.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} entity_id.`)
|
.message(`${req.T('common.invalid')} entity_id.`)
|
||||||
.api()
|
.api()
|
||||||
} else if ( req.body.entity_type === 'group' ) {
|
} else if ( req.body.entity_type === 'group' ) {
|
||||||
const Group = this.models.get('auth:Group')
|
const Group = this.models.get('auth:Group')
|
||||||
const group = await Group.findById(req.body.entity_id)
|
const group = await Group.findById(req.body.entity_id)
|
||||||
if ( !group || !group.active || !req.user.can(`auth:group:${group.id}:view`) )
|
if ( !group || !group.active || !req.user.can(`auth:group:${group.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} entity_id.`)
|
.message(`${req.T('common.invalid')} entity_id.`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !['allow', 'deny'].includes(req.body.access_type) )
|
if ( !['allow', 'deny'].includes(req.body.access_type) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} access_type. ${req.T('api:must_one')} allow, deny.`)
|
.message(`${req.T('common.invalid')} access_type. ${req.T('api:must_one')} allow, deny.`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !['application', 'api_scope'].includes(req.body.target_type) )
|
if ( !['application', 'api_scope'].includes(req.body.target_type) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} target_type. ${req.T('api:must_one')} application, api_scope.`)
|
.message(`${req.T('common.invalid')} target_type. ${req.T('api:must_one')} application, api_scope.`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Make sure the target_id is valid
|
// Make sure the target_id is valid
|
||||||
@ -122,13 +122,13 @@ class IAMController extends Controller {
|
|||||||
const app = await Application.findById(req.body.target_id)
|
const app = await Application.findById(req.body.target_id)
|
||||||
if ( !app || !app.active || !req.user.can(`app:${app.id}:view`) )
|
if ( !app || !app.active || !req.user.can(`app:${app.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} target_id.`)
|
.message(`${req.T('common.invalid')} target_id.`)
|
||||||
.api()
|
.api()
|
||||||
} else if ( req.body.target_type === 'api_scope' ) {
|
} else if ( req.body.target_type === 'api_scope' ) {
|
||||||
const api_scopes = this.canon.get('controller::api:v1:Reflect.api_scopes')()
|
const api_scopes = this.canon.get('controller::api:v1:Reflect.api_scopes')()
|
||||||
if ( !api_scopes.includes(req.body.target_id) )
|
if ( !api_scopes.includes(req.body.target_id) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} target_id.`)
|
.message(`${req.T('common.invalid')} target_id.`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,25 +152,25 @@ class IAMController extends Controller {
|
|||||||
|
|
||||||
if ( !policy || !policy.active )
|
if ( !policy || !policy.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('iam:policy_not_found'))
|
.message(req.T('iam.policy_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`iam:policy:${policy.id}:update`) )
|
if ( !req.user.can(`iam:policy:${policy.id}:update`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const required_fields = ['entity_type', 'entity_id', 'access_type', 'target_type', 'target_id']
|
const required_fields = ['entity_type', 'entity_id', 'access_type', 'target_type', 'target_id']
|
||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('api:missing_field')} ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !['user', 'group'].includes(req.body.entity_type) )
|
if ( !['user', 'group'].includes(req.body.entity_type) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} entity_type. ${req.T('api:must_one')} user, group.`)
|
.message(`${req.T('common.invalid')} entity_type. ${req.T('api.must_one')} user, group.`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Make sure the entity_id is valid
|
// Make sure the entity_id is valid
|
||||||
@ -179,25 +179,25 @@ class IAMController extends Controller {
|
|||||||
const user = await User.findById(req.body.entity_id)
|
const user = await User.findById(req.body.entity_id)
|
||||||
if ( !user || !req.user.can(`auth:user:${user.id}:view`) )
|
if ( !user || !req.user.can(`auth:user:${user.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} entity_id.`)
|
.message(`${req.T('common.invalid')} entity_id.`)
|
||||||
.api()
|
.api()
|
||||||
} else if ( req.body.entity_type === 'group' ) {
|
} else if ( req.body.entity_type === 'group' ) {
|
||||||
const Group = this.models.get('auth:Group')
|
const Group = this.models.get('auth:Group')
|
||||||
const group = await Group.findById(req.body.entity_id)
|
const group = await Group.findById(req.body.entity_id)
|
||||||
if ( !group || !group.active || !req.user.can(`auth:group:${group.id}:view`) )
|
if ( !group || !group.active || !req.user.can(`auth:group:${group.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} entity_id.`)
|
.message(`${req.T('common.invalid')} entity_id.`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !['allow', 'deny'].includes(req.body.access_type) )
|
if ( !['allow', 'deny'].includes(req.body.access_type) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} access_type. ${req.T('api:must_one')} allow, deny.`)
|
.message(`${req.T('common.invalid')} access_type. ${req.T('api.must_one')} allow, deny.`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !['application', 'api_scope'].includes(req.body.target_type) )
|
if ( !['application', 'api_scope'].includes(req.body.target_type) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} target_type. ${req.T('api:must_one')} application, api_scope.`)
|
.message(`${req.T('common.invalid')} target_type. ${req.T('api.must_one')} application, api_scope.`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Make sure the target_id is valid
|
// Make sure the target_id is valid
|
||||||
@ -206,13 +206,13 @@ class IAMController extends Controller {
|
|||||||
const app = await Application.findById(req.body.target_id)
|
const app = await Application.findById(req.body.target_id)
|
||||||
if ( !app || !app.active || !req.user.can(`app:${app.id}:view`) )
|
if ( !app || !app.active || !req.user.can(`app:${app.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} target_id.`)
|
.message(`${req.T('common.invalid')} target_id.`)
|
||||||
.api()
|
.api()
|
||||||
} else if ( req.body.target_type === 'api_scope' ) {
|
} else if ( req.body.target_type === 'api_scope' ) {
|
||||||
const api_scopes = this.canon.get('controller::api:v1:Reflect.api_scopes')()
|
const api_scopes = this.canon.get('controller::api:v1:Reflect.api_scopes')()
|
||||||
if ( !api_scopes.includes(req.body.target_id) )
|
if ( !api_scopes.includes(req.body.target_id) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`${req.T('common:invalid')} target_id.`)
|
.message(`${req.T('common.invalid')} target_id.`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,12 +231,12 @@ class IAMController extends Controller {
|
|||||||
|
|
||||||
if ( !policy || !policy.active )
|
if ( !policy || !policy.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message(req.T('iam:policy_not_found'))
|
.message(req.T('iam.policy_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`iam:policy:${policy.id}:delete`) )
|
if ( !req.user.can(`iam:policy:${policy.id}:delete`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message(req.T('api:insufficient_permissions'))
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
policy.active = false
|
policy.active = false
|
||||||
|
@ -52,12 +52,12 @@ class LDAPController extends Controller {
|
|||||||
|
|
||||||
if ( !client || !client.active )
|
if ( !client || !client.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('No client found with that ID.')
|
.message(req.T('api.client_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`ldap:client:${client.id}:view`) )
|
if ( !req.user.can(`ldap:client:${client.id}:view`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
return res.api(await client.to_api())
|
return res.api(await client.to_api())
|
||||||
@ -69,12 +69,12 @@ class LDAPController extends Controller {
|
|||||||
|
|
||||||
if ( !group || !group.active )
|
if ( !group || !group.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('No group found with that ID.')
|
.message(req.T('api.group_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`ldap:group:${group.id}:view`) )
|
if ( !req.user.can(`ldap:group:${group.id}:view`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
return res.api(await group.to_api())
|
return res.api(await group.to_api())
|
||||||
@ -83,7 +83,7 @@ class LDAPController extends Controller {
|
|||||||
async create_client(req, res, next) {
|
async create_client(req, res, next) {
|
||||||
if ( !req.user.can('ldap:client:create') )
|
if ( !req.user.can('ldap:client:create') )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// validate inputs
|
// validate inputs
|
||||||
@ -91,7 +91,7 @@ class LDAPController extends Controller {
|
|||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Missing required field: ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the uid is free
|
// Make sure the uid is free
|
||||||
@ -99,7 +99,7 @@ class LDAPController extends Controller {
|
|||||||
const existing_user = await User.findOne({ uid: req.body.uid })
|
const existing_user = await User.findOne({ uid: req.body.uid })
|
||||||
if ( existing_user )
|
if ( existing_user )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('A user with that uid already exists.')
|
.message(req.T('api.user_already_exists'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Verify password complexity
|
// Verify password complexity
|
||||||
@ -107,7 +107,7 @@ class LDAPController extends Controller {
|
|||||||
const result = zxcvbn(req.body.password)
|
const result = zxcvbn(req.body.password)
|
||||||
if ( result.score < min_score )
|
if ( result.score < min_score )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Password does not meet the minimum complexity score of ${min_score}.`)
|
.message(req.T('auth.password_complexity_fail').replace('MIN_SCORE', min_score))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Create the client
|
// Create the client
|
||||||
@ -125,7 +125,7 @@ class LDAPController extends Controller {
|
|||||||
console.log(req.body)
|
console.log(req.body)
|
||||||
if ( !req.user.can(`ldap:group:create`) )
|
if ( !req.user.can(`ldap:group:create`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// validate inputs
|
// validate inputs
|
||||||
@ -133,7 +133,7 @@ class LDAPController extends Controller {
|
|||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Missing required field: ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,13 +143,13 @@ class LDAPController extends Controller {
|
|||||||
const existing_group = await Group.findOne({ name: req.body.name })
|
const existing_group = await Group.findOne({ name: req.body.name })
|
||||||
if ( existing_group )
|
if ( existing_group )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('A group already exists with that name.')
|
.message(req.T('api.group_already_exists'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Make sure the role exists
|
// Make sure the role exists
|
||||||
if ( !this.configs.get('auth.roles')[req.body.role] )
|
if ( !this.configs.get('auth.roles')[req.body.role] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('Invalid role.')
|
.message(`${req.T('common.invalid')} role.`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const group = new Group({
|
const group = new Group({
|
||||||
@ -168,7 +168,7 @@ class LDAPController extends Controller {
|
|||||||
const user = await User.findById(user_id)
|
const user = await User.findById(user_id)
|
||||||
if ( !user )
|
if ( !user )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Invalid user ID: ${user_id}`)
|
.message(`${req.T('common.invalid')} user_id: ${user_id}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,19 +185,19 @@ class LDAPController extends Controller {
|
|||||||
|
|
||||||
if ( !client || !client.active )
|
if ( !client || !client.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('No client found with that ID.')
|
.message(req.T('api.client_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`ldap:client:${client.id}:update`) )
|
if ( !req.user.can(`ldap:client:${client.id}:update`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const required_fields = ['name', 'uid']
|
const required_fields = ['name', 'uid']
|
||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Missing required field: ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ class LDAPController extends Controller {
|
|||||||
const existing_user = await User.findOne({ uid: req.body.uid })
|
const existing_user = await User.findOne({ uid: req.body.uid })
|
||||||
if ( existing_user )
|
if ( existing_user )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('A user already exists with that uid.')
|
.message(req.T('api.user_already_exists'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
user.uid = req.body.uid
|
user.uid = req.body.uid
|
||||||
@ -229,7 +229,7 @@ class LDAPController extends Controller {
|
|||||||
const result = zxcvbn(req.body.password)
|
const result = zxcvbn(req.body.password)
|
||||||
if ( result.score < min_score )
|
if ( result.score < min_score )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Password does not meet the minimum complexity score of ${min_score}.`)
|
.message(req.T('auth.password_complexity_fail').replace('MIN_SCORE', min_score))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
await user.reset_password(req.body.password)
|
await user.reset_password(req.body.password)
|
||||||
@ -247,19 +247,19 @@ class LDAPController extends Controller {
|
|||||||
const group = await Group.findById(req.params.id)
|
const group = await Group.findById(req.params.id)
|
||||||
if ( !group || !group.active )
|
if ( !group || !group.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('No group found with that ID.')
|
.message(req.T('api.group_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`ldap:group:${group.id}:update`) )
|
if ( !req.user.can(`ldap:group:${group.id}:update`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const required_fields = ['role', 'name']
|
const required_fields = ['role', 'name']
|
||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Missing required field: ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +267,7 @@ class LDAPController extends Controller {
|
|||||||
const existing_group = await Group.findOne({ name: req.body.name })
|
const existing_group = await Group.findOne({ name: req.body.name })
|
||||||
if ( existing_group && existing_group.id !== group.id )
|
if ( existing_group && existing_group.id !== group.id )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('A group with that name already exists.')
|
.message(req.T('api.group_already_exists'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
group.name = req.body.name
|
group.name = req.body.name
|
||||||
@ -282,7 +282,7 @@ class LDAPController extends Controller {
|
|||||||
const user = await User.findById(user_id)
|
const user = await User.findById(user_id)
|
||||||
if ( !user )
|
if ( !user )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Invalid user_id: ${user_id}`)
|
.message(`${req.T('common.invalid')} user_id: ${user_id}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,12 +301,12 @@ class LDAPController extends Controller {
|
|||||||
|
|
||||||
if ( !client || !client.active )
|
if ( !client || !client.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('Client not found with that ID.')
|
.message(req.T('api.client_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`ldap:client:${client.id}:delete`) )
|
if ( !req.user.can(`ldap:client:${client.id}:delete`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const user = await client.user()
|
const user = await client.user()
|
||||||
@ -325,12 +325,12 @@ class LDAPController extends Controller {
|
|||||||
|
|
||||||
if ( !group || !group.active )
|
if ( !group || !group.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('No group found with that ID.')
|
.message(req.T('api.group_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`ldap:group:${group.id}:delete`) )
|
if ( !req.user.can(`ldap:group:${group.id}:delete`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
group.active = false
|
group.active = false
|
||||||
|
@ -24,14 +24,14 @@ class MessageController extends Controller {
|
|||||||
const banner_id = req.params.banner_id
|
const banner_id = req.params.banner_id
|
||||||
if ( !banner_id )
|
if ( !banner_id )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('Missing required parameter: banner_id')
|
.message(`${req.T('api.missing_field')} banner_id`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const Message = this.models.get('Message')
|
const Message = this.models.get('Message')
|
||||||
const message = await Message.findById(banner_id)
|
const message = await Message.findById(banner_id)
|
||||||
if ( !message )
|
if ( !message )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('Banner message not found with that ID.')
|
.message(req.T('api.banner_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( message.user_id !== req.user.id )
|
if ( message.user_id !== req.user.id )
|
||||||
|
@ -26,12 +26,12 @@ class OAuthController extends Controller {
|
|||||||
|
|
||||||
if ( !client || !client.active )
|
if ( !client || !client.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('Client not found with that ID.')
|
.message(req.T('api.client_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`oauth:client:${client.id}:view`) )
|
if ( !req.user.can(`oauth:client:${client.id}:view`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
return res.api(await client.to_api())
|
return res.api(await client.to_api())
|
||||||
@ -40,26 +40,26 @@ class OAuthController extends Controller {
|
|||||||
async create_client(req, res, next) {
|
async create_client(req, res, next) {
|
||||||
if ( !req.user.can('oauth:client:create') )
|
if ( !req.user.can('oauth:client:create') )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const required_fields = ['name', 'api_scopes', 'redirect_url']
|
const required_fields = ['name', 'api_scopes', 'redirect_url']
|
||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Missing required field: ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !Array.isArray(req.body.api_scopes) ) {
|
if ( !Array.isArray(req.body.api_scopes) ) {
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Improperly formatted field: api_scopes (should be array)`)
|
.message(`${req.T('api.improper_field')} api_scopes ${req.T('api.array')}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !is_absolute_url(req.body.redirect_url) )
|
if ( !is_absolute_url(req.body.redirect_url) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Improperly formatted field: redirect_url (should be absolute URL)`)
|
.message(`${req.T('api.improper_field')} redirect_url ${req.T('api.absolute_url')}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const Client = this.models.get('oauth:Client')
|
const Client = this.models.get('oauth:Client')
|
||||||
@ -79,30 +79,30 @@ class OAuthController extends Controller {
|
|||||||
|
|
||||||
if ( !client || !client.active )
|
if ( !client || !client.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('Client not found with that ID.')
|
.message(req.T('api.client_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`oauth:client:${client.id}:update`) )
|
if ( !req.user.can(`oauth:client:${client.id}:update`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const required_fields = ['name', 'api_scopes', 'redirect_url']
|
const required_fields = ['name', 'api_scopes', 'redirect_url']
|
||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field] )
|
if ( !req.body[field] )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Missing required field: ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !Array.isArray(req.body.api_scopes) )
|
if ( !Array.isArray(req.body.api_scopes) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Improperly formatted field: api_scopes (should be array)`)
|
.message(`${req.T('api.improper_field')} api_scopes ${req.T('api.array')}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !is_absolute_url(req.body.redirect_url) )
|
if ( !is_absolute_url(req.body.redirect_url) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Improperly formatted field: redirect_url (should be absolute URL)`)
|
.message(`${req.T('api.improper_field')} redirect_url ${req.T('api.absolute_url')}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
client.name = req.body.name
|
client.name = req.body.name
|
||||||
@ -119,12 +119,12 @@ class OAuthController extends Controller {
|
|||||||
|
|
||||||
if ( !client || !client.active )
|
if ( !client || !client.active )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('Client not found with that ID.')
|
.message(req.T('api.client_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`oauth:client:${client.id}:delete`) )
|
if ( !req.user.can(`oauth:client:${client.id}:delete`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
client.active = false
|
client.active = false
|
||||||
|
@ -21,7 +21,7 @@ class PasswordController extends Controller {
|
|||||||
created: x.created,
|
created: x.created,
|
||||||
expires: x.expires,
|
expires: x.expires,
|
||||||
active: x.active,
|
active: x.active,
|
||||||
name: x.name ?? '(unnamed)',
|
name: x.name ?? req.T('common.unnamed'),
|
||||||
uuid: x.uuid,
|
uuid: x.uuid,
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@ -30,7 +30,7 @@ class PasswordController extends Controller {
|
|||||||
async create_app_password(req, res, next) {
|
async create_app_password(req, res, next) {
|
||||||
if ( !req.body.name )
|
if ( !req.body.name )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('Missing required field: name')
|
.message(`${req.T('api.missing_field')} name`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const { password, record } = await req.user.app_password(req.body.name)
|
const { password, record } = await req.user.app_password(req.body.name)
|
||||||
@ -46,13 +46,13 @@ class PasswordController extends Controller {
|
|||||||
async delete_app_password(req, res, next) {
|
async delete_app_password(req, res, next) {
|
||||||
if ( !req.params.uuid )
|
if ( !req.params.uuid )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('Missing required parameter: uuid')
|
.message(`${req.T('api.missing_field')} uuid`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const match = req.user.app_passwords.filter(x => x.uuid === req.params.uuid)[0]
|
const match = req.user.app_passwords.filter(x => x.uuid === req.params.uuid)[0]
|
||||||
if ( !match )
|
if ( !match )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('App password not found with that UUID.')
|
.message(req.T('api.app_pw_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
req.user.app_passwords = req.user.app_passwords.filter(x => x.uuid !== req.params.uuid)
|
req.user.app_passwords = req.user.app_passwords.filter(x => x.uuid !== req.params.uuid)
|
||||||
@ -63,7 +63,7 @@ class PasswordController extends Controller {
|
|||||||
async reset_password(req, res, next) {
|
async reset_password(req, res, next) {
|
||||||
if ( !req.body.password )
|
if ( !req.body.password )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('Missing required field: password')
|
.message(`${req.T('api.missing_field')} password`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Verify password complexity
|
// Verify password complexity
|
||||||
@ -71,14 +71,14 @@ class PasswordController extends Controller {
|
|||||||
const result = zxcvbn(req.body.password)
|
const result = zxcvbn(req.body.password)
|
||||||
if ( result.score < min_score )
|
if ( result.score < min_score )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Password does not meet the minimum complexity score of ${min_score}.`)
|
.message(req.T('auth.password_complexity_fail').replace('MIN_SCORE', min_score))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Make sure it's not a re-do
|
// Make sure it's not a re-do
|
||||||
for ( const old_pw of req.user.password_resets ) {
|
for ( const old_pw of req.user.password_resets ) {
|
||||||
if ( await old_pw.check(req.body.password) ) {
|
if ( await old_pw.check(req.body.password) ) {
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`This password is a duplicate of one of your previous passwords.`)
|
.message(req.T('auth.duplicate_pw'))
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ class PasswordController extends Controller {
|
|||||||
async request_reset(req, res, next) {
|
async request_reset(req, res, next) {
|
||||||
if ( !req.body.email )
|
if ( !req.body.email )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('Missing required field: email')
|
.message(`${req.T('api.missing_field')} email`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const User = this.models.get('auth:User')
|
const User = this.models.get('auth:User')
|
||||||
|
@ -43,7 +43,7 @@ class ProfileController extends Controller {
|
|||||||
|
|
||||||
if ( !user )
|
if ( !user )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('No user found with the specified ID.')
|
.message(req.T('api.user_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Make sure the required fields are provided
|
// Make sure the required fields are provided
|
||||||
@ -51,14 +51,14 @@ class ProfileController extends Controller {
|
|||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field]?.trim() )
|
if ( !req.body[field]?.trim() )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Required field "${field}" is missing or invalid.`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the e-mail
|
// Validate the e-mail
|
||||||
if ( !Validator.validate(req.body.email) )
|
if ( !Validator.validate(req.body.email) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`"email" field must be a valid e-mail address.`)
|
.message(`${req.T('api.improper_field')} email ${req.T('api.email')}`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Update the user's profile
|
// Update the user's profile
|
||||||
@ -80,12 +80,12 @@ class ProfileController extends Controller {
|
|||||||
|
|
||||||
if ( !user )
|
if ( !user )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('No user found with the specified ID.')
|
.message(req.T('api.user_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req?.uploads?.photo )
|
if ( !req?.uploads?.photo )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('Missing required field: file')
|
.message(`${req.T('api.missing_field')} file`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
user.photo_file_id = req.uploads.photo.id
|
user.photo_file_id = req.uploads.photo.id
|
||||||
@ -101,7 +101,7 @@ class ProfileController extends Controller {
|
|||||||
|
|
||||||
if ( !user )
|
if ( !user )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('No user found with the specified ID.')
|
.message(req.T('api.user_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const photo = await user.photo()
|
const photo = await user.photo()
|
||||||
|
@ -17,7 +17,7 @@ class ReflectController extends Controller {
|
|||||||
const data = []
|
const data = []
|
||||||
for ( const token of tokens ) {
|
for ( const token of tokens ) {
|
||||||
const client = await Client.findOne({ uuid: token.clientID })
|
const client = await Client.findOne({ uuid: token.clientID })
|
||||||
let client_display = client && client.active ? client.name : '(Non-existent Client)'
|
let client_display = client && client.active ? client.name : req.T('api.nonexistent_client')
|
||||||
|
|
||||||
data.push({
|
data.push({
|
||||||
id: token.id,
|
id: token.id,
|
||||||
@ -38,7 +38,7 @@ class ReflectController extends Controller {
|
|||||||
|
|
||||||
if ( !token || token.userID !== req.user.id || token.expires <= new Date )
|
if ( !token || token.userID !== req.user.id || token.expires <= new Date )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('Token not found with that ID, or expired.')
|
.message(req.T('api.token_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
return res.api({
|
return res.api({
|
||||||
@ -55,19 +55,19 @@ class ReflectController extends Controller {
|
|||||||
|
|
||||||
if ( !req.body.client_id )
|
if ( !req.body.client_id )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('Missing required field: client_id')
|
.message(`${req.T('api.missing_field')} client_id`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const Client = this.models.get('oauth:Client')
|
const Client = this.models.get('oauth:Client')
|
||||||
const client = await Client.findOne({uuid: req.body.client_id})
|
const client = await Client.findOne({uuid: req.body.client_id})
|
||||||
if ( !client || !client.active )
|
if ( !client || !client.active )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('Invalid client_id.')
|
.message(`${req.T('common.invalid')} client_id.`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.user.can(`oauth:client:${client.id}:view`) )
|
if ( !req.user.can(`oauth:client:${client.id}:view`) )
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.message('Insufficient permissions.')
|
.message(req.T('api.insufficient_permissions'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const expires = new Date()
|
const expires = new Date()
|
||||||
@ -96,12 +96,12 @@ class ReflectController extends Controller {
|
|||||||
|
|
||||||
if ( !token || token.userID !== req.user.id || token.expires <= new Date )
|
if ( !token || token.userID !== req.user.id || token.expires <= new Date )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('Token not found with that ID, or expired.')
|
.message(req.T('api.token_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
if ( !req.body.client_id )
|
if ( !req.body.client_id )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('Missing required field: client_id')
|
.message(`${req.T('api.missing_field')} client_id`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const Client = this.models.get('oauth:Client')
|
const Client = this.models.get('oauth:Client')
|
||||||
@ -109,7 +109,7 @@ class ReflectController extends Controller {
|
|||||||
|
|
||||||
if ( !client || !client.active || !req.user.can(`oauth:client:${client.id}:view`) )
|
if ( !client || !client.active || !req.user.can(`oauth:client:${client.id}:view`) )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('Invalid client_id.')
|
.message(`${req.T('common.invalid')} client_id.`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
token.client_id = client.uuid
|
token.client_id = client.uuid
|
||||||
@ -123,7 +123,7 @@ class ReflectController extends Controller {
|
|||||||
|
|
||||||
if ( !token || token.userID !== req.user.id || token.expires <= new Date )
|
if ( !token || token.userID !== req.user.id || token.expires <= new Date )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('Token not found with that ID, or expired.')
|
.message(req.T('api.token_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
await token.delete()
|
await token.delete()
|
||||||
@ -171,7 +171,7 @@ class ReflectController extends Controller {
|
|||||||
async check_permissions(req, res, next) {
|
async check_permissions(req, res, next) {
|
||||||
if ( !req.body.permissions )
|
if ( !req.body.permissions )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('Missing permissions to check.')
|
.message(`${req.T('api.missing_field')} permissions`)
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const parsed = typeof req.body.permissions === 'string' ? this.utility.infer(req.body.permissions) : req.body.permissions
|
const parsed = typeof req.body.permissions === 'string' ? this.utility.infer(req.body.permissions) : req.body.permissions
|
||||||
|
@ -34,7 +34,7 @@ class SAMLController extends Controller {
|
|||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field]?.trim() )
|
if ( !req.body[field]?.trim() )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Missing required field: ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ class SAMLController extends Controller {
|
|||||||
|
|
||||||
if ( existing_provider )
|
if ( existing_provider )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.send(`A service provider with that entity_id already exists.`)
|
.send(req.T('api.provider_already_exists'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
@ -82,7 +82,7 @@ class SAMLController extends Controller {
|
|||||||
for ( const field of required_fields ) {
|
for ( const field of required_fields ) {
|
||||||
if ( !req.body[field].trim() )
|
if ( !req.body[field].trim() )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message(`Missing required field: ${field}`)
|
.message(`${req.T('api.missing_field')} ${field}`)
|
||||||
.api()
|
.api()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ class SAMLController extends Controller {
|
|||||||
|
|
||||||
if ( duplicate_providers.length > 0 )
|
if ( duplicate_providers.length > 0 )
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.message('A service provider already exists with that entity_id.')
|
.message(api.T('api.provider_already_exists'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
// Update the record
|
// Update the record
|
||||||
|
@ -23,7 +23,7 @@ class SettingsController extends Controller {
|
|||||||
|
|
||||||
if ( !setting )
|
if ( !setting )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('No setting exists with that key.')
|
.message(req.T('api.setting_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
return res.api(await setting.to_api())
|
return res.api(await setting.to_api())
|
||||||
@ -35,7 +35,7 @@ class SettingsController extends Controller {
|
|||||||
|
|
||||||
if ( !setting )
|
if ( !setting )
|
||||||
return res.status(404)
|
return res.status(404)
|
||||||
.message('No setting exists with that key.')
|
.message(req.T('api.setting_not_found'))
|
||||||
.api()
|
.api()
|
||||||
|
|
||||||
setting.set(req.body.value)
|
setting.set(req.body.value)
|
||||||
|
@ -21,7 +21,7 @@ class Forms extends FormController {
|
|||||||
|
|
||||||
return res.page('auth:login', {
|
return res.page('auth:login', {
|
||||||
...this.Vue.data({
|
...this.Vue.data({
|
||||||
login_message: req.session?.auth?.message || 'Please sign-in to continue.',
|
login_message: req.session?.auth?.message || req.T('auth.sign_in_to_continue'),
|
||||||
registration_enabled: await Setting.get('auth.allow_registration')
|
registration_enabled: await Setting.get('auth.allow_registration')
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
@ -29,7 +29,7 @@ class Forms extends FormController {
|
|||||||
|
|
||||||
async logout_provider_present_success(req, res, next) {
|
async logout_provider_present_success(req, res, next) {
|
||||||
return this.Vue.auth_message(res, {
|
return this.Vue.auth_message(res, {
|
||||||
message: 'You have been successfully logged out.',
|
message: req.T('auth.logged_out'),
|
||||||
next_destination: '/',
|
next_destination: '/',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@ class MFAController extends Controller {
|
|||||||
if ( req.user.mfa_enabled ) {
|
if ( req.user.mfa_enabled ) {
|
||||||
// Already set up!
|
// Already set up!
|
||||||
return this.Vue.auth_message(res, {
|
return this.Vue.auth_message(res, {
|
||||||
message: 'It looks like your account is already set up for multi-factor authentication. Unable to continue with MFA setup.',
|
message: req.T('auth.already_mfa'),
|
||||||
next_destination: '/', // TODO update this
|
next_destination: '/dash/profile',
|
||||||
button_text: 'Okay',
|
button_text: 'Okay',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -24,7 +24,7 @@ class MFAController extends Controller {
|
|||||||
async challenge(req, res, next) {
|
async challenge(req, res, next) {
|
||||||
if ( !req.user.mfa_enabled ) {
|
if ( !req.user.mfa_enabled ) {
|
||||||
return this.Vue.auth_message(res, {
|
return this.Vue.auth_message(res, {
|
||||||
message: 'Your account is not configured to use multi-factor authentication. Would you like to configure it now?',
|
message: req.T('auth.mfa_prompt'),
|
||||||
next_destination: '/auth/mfa/setup',
|
next_destination: '/auth/mfa/setup',
|
||||||
button_text: 'Setup MFA',
|
button_text: 'Setup MFA',
|
||||||
})
|
})
|
||||||
@ -42,7 +42,7 @@ class MFAController extends Controller {
|
|||||||
|
|
||||||
async get_disable(req, res, next) {
|
async get_disable(req, res, next) {
|
||||||
return this.Vue.confirm(res, {
|
return this.Vue.confirm(res, {
|
||||||
message: `You are about to disable multi-factor authentication for your account. This process will require you to re-authenticate to continue. <br><br> Proceed?`,
|
message: req.T('auth.mfa_disable_prompt'),
|
||||||
yes: '/auth/mfa/disable/process',
|
yes: '/auth/mfa/disable/process',
|
||||||
no: '/dash/profile',
|
no: '/dash/profile',
|
||||||
})
|
})
|
||||||
@ -61,7 +61,7 @@ class MFAController extends Controller {
|
|||||||
|| !Array.isArray(req.user.mfa_token.recovery_codes)
|
|| !Array.isArray(req.user.mfa_token.recovery_codes)
|
||||||
|| req.user.mfa_token.recovery_codes.length < 1
|
|| req.user.mfa_token.recovery_codes.length < 1
|
||||||
) return this.Vue.auth_message(res, {
|
) return this.Vue.auth_message(res, {
|
||||||
message: 'Unfortunately, it looks like your account does not have any MFA recovery codes generated.',
|
message: req.T('auth.mfa_no_recovery'),
|
||||||
next_destination: '/auth/mfa/challenge',
|
next_destination: '/auth/mfa/challenge',
|
||||||
button_text: 'Go Back',
|
button_text: 'Go Back',
|
||||||
})
|
})
|
||||||
|
@ -13,7 +13,7 @@ class Oauth2 extends Oauth2Controller {
|
|||||||
|
|
||||||
async authorize_post(req, res, next) {
|
async authorize_post(req, res, next) {
|
||||||
const client = await this._get_authorize_client({query: req.body})
|
const client = await this._get_authorize_client({query: req.body})
|
||||||
if ( !client ) return this._uniform(res, 'Unable to authorize client application. The application config is invalid. Please check the client ID and redirect URI and try again.')
|
if ( !client ) return this._uniform(res, req.T('unable_to_authorize'))
|
||||||
|
|
||||||
const StarshipClient = this.models.get('oauth:Client')
|
const StarshipClient = this.models.get('oauth:Client')
|
||||||
const starship_client = await StarshipClient.findOne({ active: true, uuid: client.clientID })
|
const starship_client = await StarshipClient.findOne({ active: true, uuid: client.clientID })
|
||||||
@ -25,7 +25,7 @@ class Oauth2 extends Oauth2Controller {
|
|||||||
|
|
||||||
async authorize_get(req, res, next) {
|
async authorize_get(req, res, next) {
|
||||||
const client = await this._get_authorize_client(req)
|
const client = await this._get_authorize_client(req)
|
||||||
if ( !client ) return this._uniform(res, 'Unable to authorize client application. The application config is invalid. Please check the client ID and redirect URI and try again.')
|
if ( !client ) return this._uniform(res, req.T('unable_to_authorize'))
|
||||||
const uri = new URL(req.query.redirect_uri)
|
const uri = new URL(req.query.redirect_uri)
|
||||||
|
|
||||||
const StarshipClient = this.models.get('oauth:Client')
|
const StarshipClient = this.models.get('oauth:Client')
|
||||||
@ -46,18 +46,18 @@ class Oauth2 extends Oauth2Controller {
|
|||||||
...this.Vue.data({
|
...this.Vue.data({
|
||||||
message: `<h3 class="font-weight-light">Authorize ${client.name}?</h3>
|
message: `<h3 class="font-weight-light">Authorize ${client.name}?</h3>
|
||||||
<br>
|
<br>
|
||||||
${client.name} is requesting access to your ${this.configs.get('app.name')} account. Once you grant it, you may not be prompted for permission again.
|
${req.T('auth.oauth_prompt').replace('CLIENT_NAME', client.name).replace('APP_NAME', this.configs.get('app.name'))}
|
||||||
<br><br><br>
|
<br><br><br>
|
||||||
<i><small>You will be redirected to: ${uri.host}</small></i>`,
|
<i><small>${req.T('auth.will_redirect')} ${uri.host}</small></i>`,
|
||||||
|
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
text: 'Deny',
|
text: req.T('common.deny'),
|
||||||
action: 'redirect',
|
action: 'redirect',
|
||||||
next: '/dash',
|
next: '/dash',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: 'Grant Access',
|
text: req.T('common.grant'),
|
||||||
action: 'post',
|
action: 'post',
|
||||||
params: {
|
params: {
|
||||||
redirect_uri: uri.toString(),
|
redirect_uri: uri.toString(),
|
||||||
|
@ -13,7 +13,7 @@ class TrustController extends Controller {
|
|||||||
*/
|
*/
|
||||||
async get_issue(req, res, next) {
|
async get_issue(req, res, next) {
|
||||||
if ( !req.trust.has_flow() )
|
if ( !req.trust.has_flow() )
|
||||||
return res.status(400).message('Missing trust flow data.').send()
|
return res.status(400).message(req.T('auth.missing_trust_flow')).send()
|
||||||
|
|
||||||
// Check if the session already has a token for this scope
|
// Check if the session already has a token for this scope
|
||||||
const has_scope = req.trust.has(req.trust.flow_scope())
|
const has_scope = req.trust.has(req.trust.flow_scope())
|
||||||
@ -28,22 +28,11 @@ class TrustController extends Controller {
|
|||||||
return res.page('auth:trust:grant', {
|
return res.page('auth:trust:grant', {
|
||||||
...this.Vue.data({
|
...this.Vue.data({
|
||||||
grant_code: token,
|
grant_code: token,
|
||||||
login_message: 'Please re-authenticate to continue.',
|
login_message: req.T('auth.reauth_to_continue'),
|
||||||
}),
|
}),
|
||||||
...this.Vue.session(req)
|
...this.Vue.session(req)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/*async get_continue(req, res, next) {
|
|
||||||
if ( !req.trust.has_flow() )
|
|
||||||
return res.status(400).message('Missing trust flow data.')
|
|
||||||
|
|
||||||
if ( !req.trust.in_progress() )
|
|
||||||
return res.status(401).message('No flow in progress. Please try again.')
|
|
||||||
|
|
||||||
req.trust.grant(req.trust.flow_scope())
|
|
||||||
return res.redirect(req.trust.end())
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = exports = TrustController
|
module.exports = exports = TrustController
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
const { Controller } = require('libflitter')
|
|
||||||
|
|
||||||
class GroupsController extends Controller {
|
|
||||||
static get services() {
|
|
||||||
return [...super.services, 'cobalt', 'models']
|
|
||||||
}
|
|
||||||
|
|
||||||
async get_listing(req, res, next) {
|
|
||||||
const Group = this.models.get('ldap:Group')
|
|
||||||
const groups = await Group.find()
|
|
||||||
const formatted = groups.map(x => {
|
|
||||||
return {
|
|
||||||
name: x.name,
|
|
||||||
count: x.user_ids.length,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return this.cobalt.listing(req, res, {
|
|
||||||
title: 'LDAP Groups', // TODO generalize this for SAML/OAuth2
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'Group Name',
|
|
||||||
field: 'name',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '# Users',
|
|
||||||
field: 'count',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
data: formatted,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = exports = GroupsController
|
|
@ -1,78 +0,0 @@
|
|||||||
const { Controller } = require('libflitter')
|
|
||||||
|
|
||||||
class SAMLController extends Controller {
|
|
||||||
static get services() {
|
|
||||||
return [...super.services, 'cobalt']
|
|
||||||
}
|
|
||||||
|
|
||||||
async get_sp_listing(req, res, next) {
|
|
||||||
return this.cobalt.listing(req, res, {
|
|
||||||
title: 'SAML Service Providers',
|
|
||||||
resource: 'saml/Provider',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'Provider Name',
|
|
||||||
field: 'name',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Entity ID',
|
|
||||||
field: 'entity_id',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Has SLO?',
|
|
||||||
field: 'has_slo',
|
|
||||||
renderer: 'boolean',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ACS URL',
|
|
||||||
field: 'acs_url',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
type: 'resource',
|
|
||||||
position: 'main',
|
|
||||||
action: 'insert',
|
|
||||||
text: 'Create New',
|
|
||||||
color: 'success',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async get_sp_form(req, res, next) {
|
|
||||||
return this.cobalt.form(req, res, {
|
|
||||||
item: 'SAML Service Provider',
|
|
||||||
plural: 'SAML Service Providers',
|
|
||||||
resource: 'saml/Provider',
|
|
||||||
...(req.params.id ? { existing_id: req.params.id } : {}),
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: 'Provider Name',
|
|
||||||
field: 'name',
|
|
||||||
placeholder: 'Awesome External App',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Entity ID',
|
|
||||||
field: 'entity_id',
|
|
||||||
placeholder: 'https://my.awesome.app/saml/metadata.xml',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Assertion Consumer Service URL',
|
|
||||||
field: 'acs_url',
|
|
||||||
placeholder: 'https://my.awesome.app/saml/acs',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Single-Logout URL',
|
|
||||||
field: 'slo_url',
|
|
||||||
placeholder: 'https://my.awesome.app/saml/logout',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = exports = SAMLController
|
|
@ -1,47 +0,0 @@
|
|||||||
const { Controller } = require('libflitter')
|
|
||||||
|
|
||||||
class UsersController extends Controller {
|
|
||||||
static get services() {
|
|
||||||
return [...super.services, 'models', 'cobalt']
|
|
||||||
}
|
|
||||||
|
|
||||||
async get_listing(req, res, next) {
|
|
||||||
// Columns: Username, First, Last, E-Mail
|
|
||||||
const User = this.models.get('auth:User')
|
|
||||||
const users = await User.find()
|
|
||||||
const formatted = users.map(x => {
|
|
||||||
return {
|
|
||||||
username: x.uid,
|
|
||||||
first: x.first_name,
|
|
||||||
last: x.last_name,
|
|
||||||
email: x.email,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return this.cobalt.listing(req, res, {
|
|
||||||
title: 'Users',
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'Username',
|
|
||||||
field: 'username',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'First Name',
|
|
||||||
field: 'first',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Last Name',
|
|
||||||
field: 'last',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'E-Mail Address',
|
|
||||||
field: 'email',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
data: formatted,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = exports = UsersController
|
|
@ -32,7 +32,7 @@ class SAMLController extends Controller {
|
|||||||
const can_access = await Policy.check_user_access(req.user, associated_app.id)
|
const can_access = await Policy.check_user_access(req.user, associated_app.id)
|
||||||
if ( !can_access ) {
|
if ( !can_access ) {
|
||||||
return this.Vue.auth_message(res, {
|
return this.Vue.auth_message(res, {
|
||||||
message: `Sorry, you don't have permission to access this application. Please ask your administrator to grant you access to ${associated_app.name}.`,
|
message: req.T('saml.no_access').replace('APP_NAME', associated_app.name),
|
||||||
next_destination: '/dash',
|
next_destination: '/dash',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ class SAMLController extends Controller {
|
|||||||
cert: await this.saml.public_cert(),
|
cert: await this.saml.public_cert(),
|
||||||
key: await this.saml.private_key(),
|
key: await this.saml.private_key(),
|
||||||
getPostURL: (wtrealm, wreply, req, callback) => {
|
getPostURL: (wtrealm, wreply, req, callback) => {
|
||||||
this.output.debug(`SAML Redirect URL: ${req.saml_request.service_provider.acs_url}`)
|
this.output.debug(`${req.T('saml.redirect_url')} ${req.saml_request.service_provider.acs_url}`)
|
||||||
return callback(null, req.saml_request.service_provider.acs_url) // fetch this from registered SAML app
|
return callback(null, req.saml_request.service_provider.acs_url) // fetch this from registered SAML app
|
||||||
},
|
},
|
||||||
profileMapper: user => new FlitterProfileMapper(user),
|
profileMapper: user => new FlitterProfileMapper(user),
|
||||||
@ -68,19 +68,19 @@ class SAMLController extends Controller {
|
|||||||
key: await this.saml.private_key(),
|
key: await this.saml.private_key(),
|
||||||
protocolBinding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
|
protocolBinding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
|
||||||
clearIdPSession: done => {
|
clearIdPSession: done => {
|
||||||
this.output.info(`Clearing IdP session for user: ${req.user.uid}`)
|
this.output.info(`${req.T('saml.clear_idp_session')} ${req.user.uid}`)
|
||||||
req.saml.participants.clear().then(async () => {
|
req.saml.participants.clear().then(async () => {
|
||||||
if ( this.saml.config().slo.end_coreid_session ) {
|
if ( this.saml.config().slo.end_coreid_session ) {
|
||||||
await req.user.get_provider().logout(req)
|
await req.user.get_provider().logout(req)
|
||||||
|
|
||||||
// show logout page
|
// show logout page
|
||||||
return this.Vue.auth_message(res, {
|
return this.Vue.auth_message(res, {
|
||||||
message: `You have been successfully logged out from ${this.configs.get('app.name')}.`,
|
message: req.T('auth.logged_out'),
|
||||||
next_destination: '/',
|
next_destination: '/',
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return this.Vue.auth_message(res, {
|
return this.Vue.auth_message(res, {
|
||||||
message: `You have been successfully logged out.`,
|
message: req.T('auth.logged_out'),
|
||||||
next_destination: '/',
|
next_destination: '/',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
const groups_routes = {
|
|
||||||
prefix: '/dash/groups',
|
|
||||||
|
|
||||||
middleware: [
|
|
||||||
'auth:UserOnly',
|
|
||||||
],
|
|
||||||
|
|
||||||
get: {
|
|
||||||
'/': [ 'controller::dash:Groups.get_listing' ]
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = exports = groups_routes
|
|
@ -1,13 +0,0 @@
|
|||||||
const groups_routes = {
|
|
||||||
prefix: '/dash/saml',
|
|
||||||
|
|
||||||
middleware: [
|
|
||||||
'auth:UserOnly',
|
|
||||||
],
|
|
||||||
|
|
||||||
get: {
|
|
||||||
'/service-providers': [ 'controller::dash:SAML.get_sp_listing' ]
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = exports = groups_routes
|
|
@ -1,13 +0,0 @@
|
|||||||
const user_routes = {
|
|
||||||
prefix: '/dash/users',
|
|
||||||
|
|
||||||
middleware: [
|
|
||||||
'auth:UserOnly',
|
|
||||||
],
|
|
||||||
|
|
||||||
get: {
|
|
||||||
'/': [ 'controller::dash:Users.get_listing' ]
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = exports = user_routes
|
|
@ -6,6 +6,20 @@ module.exports = exports = {
|
|||||||
group_already_exists: 'A group with that name already exists.',
|
group_already_exists: 'A group with that name already exists.',
|
||||||
|
|
||||||
user_not_found: 'User not found with that ID.',
|
user_not_found: 'User not found with that ID.',
|
||||||
|
user_already_exists: 'A user with that identifier already exists.',
|
||||||
|
|
||||||
|
client_not_found: 'Client not found with that ID.',
|
||||||
|
nonexistent_client: '(Non-existent Client)',
|
||||||
|
|
||||||
|
token_not_found: 'Token not found with that ID, or the token has expired.',
|
||||||
|
|
||||||
|
provider_already_exists: 'A service provider with that entity_id already exists.',
|
||||||
|
|
||||||
|
setting_not_found: 'No such setting exists with that key.',
|
||||||
|
|
||||||
|
banner_not_found: 'Banner message not found with that ID.',
|
||||||
|
|
||||||
|
app_pw_not_found: 'App password not found with that UUID.',
|
||||||
|
|
||||||
invalid_ldap_client_id: 'Invalid ldap_client_id:',
|
invalid_ldap_client_id: 'Invalid ldap_client_id:',
|
||||||
invalid_oauth_client_id: 'Invalid oauth_client_id:',
|
invalid_oauth_client_id: 'Invalid oauth_client_id:',
|
||||||
@ -18,6 +32,9 @@ module.exports = exports = {
|
|||||||
},
|
},
|
||||||
improper_field: 'Improperly formatted field:',
|
improper_field: 'Improperly formatted field:',
|
||||||
alphanum_underscores: '(alphanumeric/underscores)',
|
alphanum_underscores: '(alphanumeric/underscores)',
|
||||||
|
array: '(array)',
|
||||||
|
email: '(email)',
|
||||||
|
absolute_url: '(should be absolute URL)',
|
||||||
provide_one: 'Please provide one of:',
|
provide_one: 'Please provide one of:',
|
||||||
must_one: 'Must be one of:',
|
must_one: 'Must be one of:',
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,25 @@ module.exports = exports = {
|
|||||||
no_mfa: 'Your user is not configured to use MFA.',
|
no_mfa: 'Your user is not configured to use MFA.',
|
||||||
already_has_mfa: 'MFA is already configured for your user.',
|
already_has_mfa: 'MFA is already configured for your user.',
|
||||||
password_complexity_fail: 'Password does not meet the minimum complexity score of MIN_SCORE.',
|
password_complexity_fail: 'Password does not meet the minimum complexity score of MIN_SCORE.',
|
||||||
|
duplicate_pw: 'This password is a duplicate of one of your previous passwords.',
|
||||||
invalid_trap: 'Invalid trap type.',
|
invalid_trap: 'Invalid trap type.',
|
||||||
|
|
||||||
unable_to_grant_trust: 'Unable to grant trust. Grant token is invalid.',
|
unable_to_grant_trust: 'Unable to grant trust. Grant token is invalid.',
|
||||||
|
missing_trust_flow: 'Missing trust flow data.',
|
||||||
|
|
||||||
invalid_un_or_pw: 'Invalid username or password.',
|
invalid_un_or_pw: 'Invalid username or password.',
|
||||||
unable_to_complete: 'Unable to complete authentication: one or more errors occurred',
|
unable_to_complete: 'Unable to complete authentication: one or more errors occurred',
|
||||||
|
|
||||||
|
sign_in_to_continue: 'Please, sign-in to continue.',
|
||||||
|
logged_out: 'You have been suggessfully logged out.',
|
||||||
|
|
||||||
|
already_mfa: 'It looks like your account is already set up for multi-factor authentication. Unable to continue with MFA setup.',
|
||||||
|
mfa_prompt: 'Your account is not configured to use multi-factor authentication. Would you like to configure it now?',
|
||||||
|
mfa_disable_prompt: 'You are about to disable multi-factor authentication for your account. This process will require you to re-authenticate to continue. <br><br> Proceed?',
|
||||||
|
mfa_no_recovery: 'Unfortunately, it looks like your account does not have any MFA recovery codes generated.',
|
||||||
|
unable_to_authorize: 'Unable to authorize client application. The application config is invalid. Please check the client ID and redirect URI and try again.',
|
||||||
|
|
||||||
|
oauth_prompt: 'CLIENT_NAME is requesting access to your APP_NAME account. Once you grant it, you may not be prompted for permission again.',
|
||||||
|
will_redirect: 'You will be redirected to:',
|
||||||
|
reauth_to_continue: 'Please re-authenticate to continue.',
|
||||||
}
|
}
|
||||||
|
@ -6,4 +6,8 @@ module.exports = exports = {
|
|||||||
log_out: 'Log out',
|
log_out: 'Log out',
|
||||||
|
|
||||||
invalid: 'Invalid',
|
invalid: 'Invalid',
|
||||||
|
unnamed: '(unnamed)',
|
||||||
|
|
||||||
|
deny: 'Deny',
|
||||||
|
grant: 'Grant Access',
|
||||||
}
|
}
|
||||||
|
5
locale/en_US/saml.locale.js
Normal file
5
locale/en_US/saml.locale.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module.exports = exports = {
|
||||||
|
no_access: 'Sorry, you don\'t have permission to access this application. Please ask your administrator to grant you access to APP_NAME.',
|
||||||
|
redirect_url: 'SAML Redirect URL:',
|
||||||
|
clear_idp_session: 'Clearing IdP session for user:'
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user