feat: register validation + create + admin improvements

This commit is contained in:
Nicolas Giard
2018-12-17 00:51:52 -05:00
parent 17244a0cb3
commit 901dbb98e0
25 changed files with 668 additions and 62 deletions

View File

@@ -18,6 +18,13 @@ router.get('/logout', function (req, res) {
res.redirect('/')
})
/**
* Register form
*/
router.get('/register', function (req, res, next) {
res.render('register')
})
/**
* JWT Public Endpoints
*/

View File

@@ -38,7 +38,7 @@ module.exports = {
AuthenticationMutation: {
async login(obj, args, context) {
try {
let authResult = await WIKI.models.users.login(args, context)
const authResult = await WIKI.models.users.login(args, context)
return {
...authResult,
responseResult: graphHelper.generateSuccess('Login success')
@@ -49,7 +49,7 @@ module.exports = {
},
async loginTFA(obj, args, context) {
try {
let authResult = await WIKI.models.users.loginTFA(args, context)
const authResult = await WIKI.models.users.loginTFA(args, context)
return {
...authResult,
responseResult: graphHelper.generateSuccess('TFA success')
@@ -58,6 +58,22 @@ module.exports = {
return graphHelper.generateError(err)
}
},
async register(obj, args, context) {
try {
await WIKI.models.users.register(args, context)
const authResult = await WIKI.models.users.login({
username: args.email,
password: args.password,
strategy: 'local'
}, context)
return {
jwt: authResult.jwt,
responseResult: graphHelper.generateSuccess('Registration success')
}
} catch (err) {
return graphHelper.generateError(err)
}
},
async updateStrategies(obj, args, context) {
try {
for (let str of args.strategies) {

View File

@@ -36,6 +36,12 @@ type AuthenticationMutation {
securityCode: String!
): DefaultResponse
register(
email: String!
password: String!
name: String!
): AuthenticationRegisterResponse
updateStrategies(
strategies: [AuthenticationStrategyInput]
): DefaultResponse @auth(requires: ["manage:system"])
@@ -69,6 +75,11 @@ type AuthenticationLoginResponse {
tfaLoginToken: String
}
type AuthenticationRegisterResponse {
responseResult: ResponseStatus
jwt: String
}
input AuthenticationStrategyInput {
isEnabled: Boolean!
key: String!

View File

@@ -1,30 +1,44 @@
class BaseError extends Error {
constructor (message) {
super(message)
this.name = this.constructor.name
Error.captureStackTrace(this, this.constructor)
}
}
class AuthGenericError extends BaseError { constructor (message = 'An unexpected error occured during login.') { super(message) } }
class AuthLoginFailed extends BaseError { constructor (message = 'Invalid email / username or password.') { super(message) } }
class AuthProviderInvalid extends BaseError { constructor (message = 'Invalid authentication provider.') { super(message) } }
class AuthTFAFailed extends BaseError { constructor (message = 'Incorrect TFA Security Code.') { super(message) } }
class AuthTFAInvalid extends BaseError { constructor (message = 'Invalid TFA Security Code or Login Token.') { super(message) } }
class BruteInstanceIsInvalid extends BaseError { constructor (message = 'Invalid Brute Force Instance.') { super(message) } }
class BruteTooManyAttempts extends BaseError { constructor (message = 'Too many attempts! Try again later.') { super(message) } }
class LocaleInvalidNamespace extends BaseError { constructor (message = 'Invalid locale or namespace.') { super(message) } }
class UserCreationFailed extends BaseError { constructor (message = 'An unexpected error occured during user creation.') { super(message) } }
const CustomError = require('custom-error-instance')
module.exports = {
BaseError,
AuthGenericError,
AuthLoginFailed,
AuthProviderInvalid,
AuthTFAFailed,
AuthTFAInvalid,
BruteInstanceIsInvalid,
BruteTooManyAttempts,
LocaleInvalidNamespace,
UserCreationFailed
AuthGenericError: CustomError('AuthGenericError', {
message: 'An unexpected error occured during login.',
code: 1001
}),
AuthLoginFailed: CustomError('AuthLoginFailed', {
message: 'Invalid email / username or password.',
code: 1002
}),
AuthProviderInvalid: CustomError('AuthProviderInvalid', {
message: 'Invalid authentication provider.',
code: 1003
}),
AuthAccountAlreadyExists: CustomError('AuthAccountAlreadyExists', {
message: 'An account already exists using this email address.',
code: 1004
}),
AuthTFAFailed: CustomError('AuthTFAFailed', {
message: 'Incorrect TFA Security Code.',
code: 1005
}),
AuthTFAInvalid: CustomError('AuthTFAInvalid', {
message: 'Invalid TFA Security Code or Login Token.',
code: 1006
}),
BruteInstanceIsInvalid: CustomError('BruteInstanceIsInvalid', {
message: 'Invalid Brute Force Instance.',
code: 1007
}),
BruteTooManyAttempts: CustomError('BruteTooManyAttempts', {
message: 'Too many attempts! Try again later.',
code: 1008
}),
LocaleInvalidNamespace: CustomError('LocaleInvalidNamespace', {
message: 'Invalid locale or namespace.',
code: 1009
}),
UserCreationFailed: CustomError('UserCreationFailed', {
message: 'An unexpected error occured during user creation.',
code: 1010
})
}

View File

@@ -292,4 +292,23 @@ module.exports = class User extends Model {
}
throw new WIKI.Error.AuthTFAInvalid()
}
static async register ({ email, password, name }, context) {
const usr = await WIKI.models.users.query().findOne({ email, providerKey: 'local' })
if (!usr) {
await WIKI.models.users.query().insert({
provider: 'local',
email,
name,
password,
locale: 'en',
defaultEditor: 'markdown',
tfaIsActive: false,
isSystem: false
})
return true
} else {
throw new WIKI.Error.AuthAccountAlreadyExists()
}
}
}

View File

@@ -0,0 +1,5 @@
extends master.pug
block body
#root.is-fullscreen
register