diff --git a/src/create-user/controller.ts b/src/create-user/controller.ts new file mode 100644 index 00000000..cf391fe0 --- /dev/null +++ b/src/create-user/controller.ts @@ -0,0 +1,60 @@ +import Controller from '@curveball/controller'; +import { Context } from '@curveball/core'; +import { NotFound, UnprocessableEntity } from '@curveball/http-errors'; +import * as userService from '../user/service'; +import { UserTypeList } from '../user/types'; +import { createUserForm } from './formats/html'; + +class CreateUserController extends Controller { + + async get(ctx: Context) { + + ctx.response.type = 'text/html'; + ctx.response.body = createUserForm(ctx.query.msg, ctx.query.error); + } + + async post(ctx: Context) { + + const identity = ctx.request.body.identity; + const nickname = ctx.request.body.nickname; + const type = ctx.request.body.type; + + + if (!identity || !identity.contains(':') || identity.contains(' ')) { + throw new UnprocessableEntity('Identity must exist and must be a url'); + } + if (nickname.length < 1) { + throw new UnprocessableEntity('nickname must contain at least 1 character'); + } + + if (!UserTypeList.includes(type)) { + throw new UnprocessableEntity('type must be one of ' + UserTypeList.join(', ')); + } + + try { + await userService.findByIdentity(ctx.request.body.identity); + ctx.status = 303; + ctx.response.headers.set('Location', '/create-user?error=User+already+exists'); + return; + } catch (err) { + if (!(err instanceof NotFound)) { + throw err; + } + } + + const newUser = await userService.save({ + identity: identity, + nickname: nickname, + created: new Date(), + type: type, + active: 'active' in ctx.request.body + }); + + ctx.response.status = 303; + ctx.response.headers.set('Location', '/user/' + newUser.id); + + } + +} + +export default new CreateUserController(); diff --git a/src/create-user/formats/html.ts b/src/create-user/formats/html.ts new file mode 100644 index 00000000..48749427 --- /dev/null +++ b/src/create-user/formats/html.ts @@ -0,0 +1,13 @@ +import { render } from '../../templates'; +import { UserTypeList } from '../../user/types'; + +export function createUserForm(msg: string, error: string) { + + return render('create-user', { + title: 'Create User', + msg: msg, + erro: error, + type: UserTypeList, + action: '/create-user' + }); +} diff --git a/src/routes.ts b/src/routes.ts index f7658072..14889d12 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -1,6 +1,7 @@ import router from '@curveball/router'; import blob from './blob/controller'; import changePassword from './changepassword/controller'; +import createUser from './create-user/controller'; import group from './group/controller/collection'; import health from './health/controller'; import home from './home/controller'; @@ -23,6 +24,7 @@ import user from './user/controller/item'; const routes = [ router('/', home), router('/user', users), + router('/create-user', createUser), router('/user/:id', user), router('/user/:id/log', userLog), router('/user/:id/member', group), diff --git a/src/user/formats/hal.ts b/src/user/formats/hal.ts index fcf58d3d..d786a1dc 100644 --- a/src/user/formats/hal.ts +++ b/src/user/formats/hal.ts @@ -5,8 +5,9 @@ export function collection(users: User[]) { const hal: any = { _links: { - self: { href: '/user' }, - item: [], + 'self': { href: '/user' }, + 'item': [], + 'create-form': { href: '/create-user', title: 'Create New User'} }, total: users.length, }; diff --git a/templates/create-user.hbs b/templates/create-user.hbs new file mode 100644 index 00000000..3bab0f21 --- /dev/null +++ b/templates/create-user.hbs @@ -0,0 +1,46 @@ +
+ + {{# if msg}} +
{{ msg }}
+ {{/if}} + {{# if error}} +
{{ error }}
+ {{/if}} + +
+ + + + + + + +
+ +
+ +
+ + {{#each hiddenFields}} + + {{/each}} + +
\ No newline at end of file