diff --git a/api/src/auth/dto/auth.jwt.dto.ts b/api/src/auth/dto/auth.jwt.dto.ts index 7ae87476..bccf87ab 100644 --- a/api/src/auth/dto/auth.jwt.dto.ts +++ b/api/src/auth/dto/auth.jwt.dto.ts @@ -2,8 +2,9 @@ import { ApiModelProperty } from '@nestjs/swagger'; export class AuthJwtDto { @ApiModelProperty() - access_token: string; + token: { + accessToken: string; - @ApiModelProperty() - refresh_token: string; + refreshToken: string; + } } diff --git a/api/src/auth/services/auth.service.ts b/api/src/auth/services/auth.service.ts index a06175e9..dc26649d 100644 --- a/api/src/auth/services/auth.service.ts +++ b/api/src/auth/services/auth.service.ts @@ -51,20 +51,22 @@ export class AuthService { const payload = { id: user.id, username: user.username, - roles: user.roles, + scope: user.roles, }; return { - access_token: this.jwtService.sign(payload), - // TODO add refresh token invalidation uppon usage! They should only work once - refresh_token: this.jwtService.sign( - { - ...payload, - refresh: true - }, - { - expiresIn: '30days', - } - ), + token: { + accessToken: this.jwtService.sign(payload), + // TODO add refresh token invalidation uppon usage! They should only work once + refreshToken: this.jwtService.sign( + { + ...payload, + refresh: true + }, + { + expiresIn: '30days', + } + ), + } }; } } diff --git a/api/src/auth/services/register.service.ts b/api/src/auth/services/register.service.ts index 66734a41..259bcf68 100644 --- a/api/src/auth/services/register.service.ts +++ b/api/src/auth/services/register.service.ts @@ -13,8 +13,6 @@ export class RegisterService { ) {} async register (username: string, email: string, password: string): Promise { - // TODO actually create user - let user = new User() user.email = email user.username = username diff --git a/api/src/form/controllers/form.controller.ts b/api/src/form/controllers/form.controller.ts index 9a445818..1ae21758 100644 --- a/api/src/form/controllers/form.controller.ts +++ b/api/src/form/controllers/form.controller.ts @@ -12,9 +12,12 @@ export class FormController { @Get() @UseGuards(AuthGuard('jwt')) - async list(@Request() req): Promise { - throw new NotImplementedException() + async list(@Request() req): Promise { + // TODO calculate total forms, add for pagination + const results = await this.formService.findBy({}) + return results.map(form => new FormDto(form)) } + @Post() @UseGuards(AuthGuard('jwt')) async create(@Request() req): Promise { diff --git a/api/src/form/dto/form.dto.ts b/api/src/form/dto/form.dto.ts index 34f027f0..1870568d 100644 --- a/api/src/form/dto/form.dto.ts +++ b/api/src/form/dto/form.dto.ts @@ -8,10 +8,32 @@ export class FormDto { @ApiModelProperty() title: string; - fields: []; + @ApiModelProperty() + live: boolean; + + @ApiModelProperty() + created: Date; + + @ApiModelProperty() + lastModified: Date; + + @ApiModelProperty() + fields: any; + + @ApiModelProperty() + info: { + responses: number; + } constructor(partial: Partial
) { - this.id = partial._id.toString(); + this.id = partial._id.toString() this.title = partial.title + this.live = partial.isLive + this.created = partial.created + this.lastModified = partial.lastModified + this.fields = partial.form_fields + this.info = { + responses: 0 // TODO + } } } diff --git a/api/src/form/models/form.model.ts b/api/src/form/models/form.model.ts index 6b9dc9bd..482da8c1 100644 --- a/api/src/form/models/form.model.ts +++ b/api/src/form/models/form.model.ts @@ -17,8 +17,10 @@ export class Form extends Typegoose { }) readonly title: string; + @prop() readonly created: any; + @prop() readonly lastModified: any; @prop({ diff --git a/api/src/form/services/form.service.ts b/api/src/form/services/form.service.ts index b592a317..8e67bfc9 100644 --- a/api/src/form/services/form.service.ts +++ b/api/src/form/services/form.service.ts @@ -2,6 +2,7 @@ import {Injectable} from '@nestjs/common'; import { InjectModel } from 'nestjs-typegoose'; import { ModelType } from 'typegoose'; import {Form} from "../models/form.model" +import {User} from "../../user/models/user.model" @Injectable() export class FormService { @@ -10,4 +11,8 @@ export class FormService { async findById(id: string): Promise { return await this.formModel.findById(id).exec() } + + async findBy(conditions): Promise { + return await this.formModel.find(conditions).exec() + } } diff --git a/api/src/main.ts b/api/src/main.ts index 022d3a5f..62b27df4 100644 --- a/api/src/main.ts +++ b/api/src/main.ts @@ -6,10 +6,7 @@ import { useContainer } from "class-validator" const pkg = require('../package.json') async function bootstrap() { - const app = await NestFactory.create(AppModule); - - // app.enableCors({ origin: '*' }); - // app.getHttpAdapter().options('*', cors()); + const app = await NestFactory.create(AppModule, { cors: true }); useContainer(app.select(AppModule), { fallbackOnErrors: true }); diff --git a/api/src/user/controllers/user.controller.ts b/api/src/user/controllers/user.controller.ts index fac9543e..5348c2b9 100644 --- a/api/src/user/controllers/user.controller.ts +++ b/api/src/user/controllers/user.controller.ts @@ -3,6 +3,7 @@ import { AuthGuard } from '@nestjs/passport'; import { ApiBearerAuth, ApiImplicitQuery, ApiResponse, ApiUseTags } from "@nestjs/swagger" import { UserService } from "../services/user.service" import { UserDto } from "../dto/user.dto" +import {FormDto} from "../../form/dto/form.dto" @ApiUseTags('users') @ApiBearerAuth() @@ -12,8 +13,10 @@ export class UserController { @Get() @UseGuards(AuthGuard('jwt')) - async list(@Request() req): Promise { - throw new NotImplementedException() + async list(@Request() req): Promise { + // TODO calculate total forms, add for pagination + const results = await this.userService.findBy({}) + return results.map(form => new UserDto(form)) } @ApiResponse({ status: 200, description: 'User Object', type: UserDto}) diff --git a/api/src/user/dto/user.dto.ts b/api/src/user/dto/user.dto.ts index 967fde05..c19fd3d5 100644 --- a/api/src/user/dto/user.dto.ts +++ b/api/src/user/dto/user.dto.ts @@ -8,8 +8,20 @@ export class UserDto { @ApiModelProperty() username: string; + @ApiModelProperty() + email: string; + + @ApiModelProperty() + roles: string[]; + + @ApiModelProperty() + created: Date; + constructor(partial: Partial) { - this.id = partial._id.toString(); + this.id = partial._id.toString() this.username = partial.username + this.email = partial.email + this.roles = partial.roles + this.created = partial.created } } diff --git a/api/src/user/services/user.service.ts b/api/src/user/services/user.service.ts index e349446a..f320fe2a 100644 --- a/api/src/user/services/user.service.ts +++ b/api/src/user/services/user.service.ts @@ -33,6 +33,10 @@ export class UserService { return await this.userModel.findOne(conditions).exec() } + async findBy(conditions): Promise { + return await this.userModel.find(conditions).exec() + } + async save(user: User): Promise { let model = new this.userModel(user) return await model.save() diff --git a/ui/assets/css/base.scss b/ui/assets/css/base.scss index d1baa857..9a315ac6 100644 --- a/ui/assets/css/base.scss +++ b/ui/assets/css/base.scss @@ -1,7 +1,9 @@ $accent: #fae596; $primary: #3fb0ac; -html { +@import url('https://fonts.googleapis.com/icon?family=Material+Icons'); + +1html { font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; font-size: 16px; @@ -13,6 +15,23 @@ html { box-sizing: border-box; } +.bg-primary { + &.navbar-dark, + &.dark { + background-color: #173e43 !important; + } + + &.dark { + a { + color: #dddfd4; + + &:hover { + color: #fae596; + } + } + } +} + .btn-primary { color: #fff; background-color: $primary; diff --git a/ui/layouts/admin.vue b/ui/layouts/admin.vue index 98425752..bfa00075 100644 --- a/ui/layouts/admin.vue +++ b/ui/layouts/admin.vue @@ -1,5 +1,57 @@ + + diff --git a/ui/layouts/screen.vue b/ui/layouts/screen.vue index 8518930c..1d942c63 100644 --- a/ui/layouts/screen.vue +++ b/ui/layouts/screen.vue @@ -1,5 +1,5 @@