add settings endpoint

This commit is contained in:
Michael Schramm 2020-06-08 15:17:46 +02:00
parent 57e13b84df
commit b16d2f49c3
10 changed files with 149 additions and 0 deletions

View File

@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
### Added
- `SIGNUP_DISABLED=true` to prevent users from signing up
### Changed
### Fixed

View File

@ -0,0 +1,25 @@
import { Field, ObjectType } from '@nestjs/graphql';
import { GraphQLInt } from 'graphql';
import {SettingModel} from './setting.model'
@ObjectType('PagerSetting')
export class PagerSettingModel {
@Field(() => [SettingModel])
entries: SettingModel[]
@Field(() => GraphQLInt)
total: number
@Field(() => GraphQLInt)
limit: number
@Field(() => GraphQLInt)
start: number
constructor(entries: SettingModel[], total: number, limit: number, start: number) {
this.entries = entries
this.total = total
this.limit = limit
this.start = start
}
}

View File

@ -0,0 +1,24 @@
import { Field, ID, ObjectType } from '@nestjs/graphql';
@ObjectType('Setting')
export class SettingModel {
@Field(() => ID)
readonly key: string
@Field()
readonly value: string
@Field()
readonly isTrue: boolean
@Field()
readonly isFalse: boolean
constructor(key: string, value: string) {
this.key = key
this.value = value
this.isTrue = value.toLowerCase() === 'true' || value === '1'
this.isFalse = !this.isTrue
}
}

View File

@ -4,12 +4,14 @@ import { PinoLogger } from 'nestjs-pino/dist';
import { AuthJwtModel } from '../../dto/auth/auth.jwt.model';
import { UserCreateInput } from '../../dto/user/user.create.input';
import { AuthService } from '../../service/auth/auth.service';
import {SettingService} from '../../service/setting.service'
import { UserCreateService } from '../../service/user/user.create.service';
@Injectable()
export class AuthRegisterResolver {
constructor(
private readonly createUser: UserCreateService,
private readonly settingService: SettingService,
private readonly auth: AuthService,
private readonly logger: PinoLogger,
) {
@ -19,6 +21,10 @@ export class AuthRegisterResolver {
async authRegister(
@Args({ name: 'user' }) data: UserCreateInput,
): Promise<AuthJwtModel> {
if (await this.settingService.isTrue('SIGNUP_DISABLED')) {
throw new Error('signup disabled')
}
this.logger.info({
email: data.email,
username: data.username,

View File

@ -1,6 +1,7 @@
import { authServices } from './auth';
import { formResolvers } from './form';
import { profileResolvers } from './profile';
import {settingsResolvers} from './setting'
import { StatusResolver } from './status.resolver';
import { submissionResolvers } from './submission';
import { userResolvers } from './user';
@ -12,4 +13,5 @@ export const resolvers = [
...profileResolvers,
...formResolvers,
...submissionResolvers,
...settingsResolvers,
]

View File

@ -0,0 +1,7 @@
import {SettingMutation} from './setting.mutation'
import {SettingResolver} from './setting.resolver'
export const settingsResolvers = [
SettingResolver,
SettingMutation,
]

View File

@ -0,0 +1,8 @@
import {Roles} from '../../decorator/roles.decorator'
export class SettingMutation {
@Roles('superuser')
setSetting(key: string, value: string) {
// TODO https://github.com/ohmyform/api/issues/3
}
}

View File

@ -0,0 +1,44 @@
import {ConfigService} from '@nestjs/config'
import {Args, ID, Query} from '@nestjs/graphql'
import {Roles} from '../../decorator/roles.decorator'
import {User} from '../../decorator/user.decorator'
import {PagerSettingModel} from '../../dto/setting/pager.setting.model'
import {SettingModel} from '../../dto/setting/setting.model'
import {UserModel} from '../../dto/user/user.model'
import {UserDocument} from '../../schema/user.schema'
import {SettingService} from '../../service/setting.service'
export class SettingResolver {
private publicKeys: string[] = [
'SIGNUP_DISABLED',
]
constructor(
private readonly settingService: SettingService,
) {
}
@Query(() => PagerSettingModel)
@Roles('superuser')
async getSettings(): Promise<PagerSettingModel> {
// TODO https://github.com/ohmyform/api/issues/3
return new PagerSettingModel(
[],
0,
0,
0,
)
}
@Query(() => SettingModel)
async getSetting(
@Args('key', {type: () => ID}) key: string,
@User() user: UserDocument,
): Promise<SettingModel> {
if (!this.publicKeys.includes(key) && !user.roles.includes('superuser')) {
throw new Error(`no access to key ${key}`)
}
return await this.settingService.getByKey(key)
}
}

View File

@ -8,6 +8,7 @@ import { formServices } from './form';
import { InstallationMetricsService } from './installation.metrics.service';
import { MailService } from './mail.service';
import { profileServices } from './profile';
import {SettingService} from './setting.service'
import { submissionServices } from './submission';
import { userServices } from './user';
@ -17,6 +18,7 @@ export const services = [
...formServices,
...authServices,
...submissionServices,
SettingService,
MailService,
InstallationMetricsService,
{

View File

@ -0,0 +1,28 @@
import {Injectable} from '@nestjs/common'
import {ConfigService} from '@nestjs/config'
import {SettingModel} from '../dto/setting/setting.model'
@Injectable()
export class SettingService {
constructor(
private readonly configService: ConfigService,
) {
}
async getByKey(key: string): Promise<SettingModel> {
switch (key) {
case 'SIGNUP_DISABLED':
return new SettingModel(key, this.configService.get(key))
}
throw new Error(`no config stored for key ${key}`)
}
async isTrue(key: string): Promise<boolean> {
return (await this.getByKey(key)).isTrue
}
async isFalse(key: string): Promise<boolean> {
return (await this.getByKey(key)).isFalse
}
}