@ -10,11 +10,12 @@ import {
import { Server , IncomingMessage , ServerResponse } from 'http'
import { tokenResponseSchema , userSchema } from '../../schemas'
import { MIN_ID_LENGTH , MAX_ID_LENGTH , MAX_NAME_LENGTH , MIN_PASSWORD_LENGTH } from '../../constants'
import { tokenResponseSchema , userSchema , errorSchema } from '../../schemas'
import { createAccessToken , createRefreshToken } from '../../lib/authentication'
import { hashPassword , verifyPassword , JWT } from '../../lib/crypto'
import { containerFor , getItem , normalize } from '../../lib/database'
import { errorSchema , badRequestError , unauthorizedError , serverError } from '../../lib/errors'
import { badRequestError , unauthorizedError , serverError } from '../../lib/errors'
import { tokenFromHeader } from '../../lib/http'
import { IUser , IUserToken , IGroup , IGroupPartial } from '../../types/collections'
@ -27,7 +28,7 @@ function registerRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe
name : string
email : string
password : string
groupId : string
group : string
}
const options : RouteShorthandOptions = {
@ -36,11 +37,24 @@ function registerRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe
type : 'object' ,
required : [ 'id' , 'email' , 'password' ] ,
properties : {
id : { type : 'string' } ,
name : { type : 'string' } ,
email : { type : 'string' } ,
password : { type : 'string' } ,
groupId : { type : 'string' } ,
id : {
type : 'string' ,
minLength : MIN_ID_LENGTH ,
maxLength : MAX_ID_LENGTH ,
} ,
name : {
type : 'string' ,
maxLength : MAX_NAME_LENGTH ,
} ,
email : {
type : 'string' ,
format : 'email' ,
} ,
password : {
type : 'string' ,
minLength : MIN_PASSWORD_LENGTH ,
} ,
group : { type : 'string' } ,
} ,
} ,
response : {
@ -53,17 +67,9 @@ function registerRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe
server . post < DefaultQuery , DefaultParams , DefaultHeaders , Body > ( '/api/register' , options , async ( request , reply ) = > {
if ( ! server . database ) return serverError ( reply )
const { name , email , password , groupId } = request . body
const { name , email , password } = request . body
const id = normalize ( request . body . id )
if ( ! id || id === '' ) return badRequestError ( reply , 'id is required' , 'id' )
if ( id . length < 5 || id . length > 20 ) return badRequestError ( reply , 'id must be between 5 and 20 characters' , 'id' )
if ( name && name . length > 40 ) return badRequestError ( reply , 'name must be less than 40 characters' , 'name' )
if ( ! email || email === '' ) return badRequestError ( reply , 'email is required' , 'email' )
if ( email . length < 5 ) return badRequestError ( reply , 'email must be at least 5 characters' , 'email' )
if ( ! password || password === '' ) return badRequestError ( reply , 'password is required' , 'password' )
if ( password . length < 5 ) return badRequestError ( reply , 'password must be at least 5 characters' , 'password' )
const userContainer = containerFor ( server . database . client , 'Users' )
const existingUser = await getItem < IUser > ( userContainer , id , request . log )
if ( existingUser ) return badRequestError ( reply , 'User id already taken' , 'id' )
@ -71,8 +77,8 @@ function registerRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe
let userPending = false
let groupPartial : IGroupPartial | undefined
if ( groupId ) {
const group = await getItem < IGroup > ( containerFor ( server . database . client , 'Groups' ) , groupId , request . log )
if ( request . body . group ) {
const group = await getItem < IGroup > ( containerFor ( server . database . client , 'Groups' ) , request . body . group , request . log )
if ( ! group ) return badRequestError ( reply , 'Group not found' , 'groupId' )
if ( ! group . open ) return badRequestError ( reply , 'Group registration closed' , 'groupId' )
@ -100,6 +106,7 @@ function registerRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe
subscriberCount : 0 ,
subscribedCount : 0 ,
pending : userPending ,
requiresApproval : false ,
privacy : 'public' ,
paid : false ,
about : '' ,
@ -247,6 +254,7 @@ function selfRoute(server: FastifyInstance<Server, IncomingMessage, ServerRespon
schema : {
response : {
200 : userSchema ,
400 : errorSchema ,
} ,
} ,
}