type Organizer { | type Organizer { | ||||
_id: UUID! | _id: UUID! | ||||
name: String! | name: String! | ||||
plz: Int | |||||
ort: String | |||||
logo: String | logo: String | ||||
_admins: [UUID!] | _admins: [UUID!] | ||||
_organizers: [UUID!] | _organizers: [UUID!] | ||||
Apparatus(id: UUID!): Apparatus | Apparatus(id: UUID!): Apparatus | ||||
ApparatusFind(offset: Int, limit: Int, name: String): [Apparatus!] | ApparatusFind(offset: Int, limit: Int, name: String): [Apparatus!] | ||||
Organizer(id: UUID!): Organizer | Organizer(id: UUID!): Organizer | ||||
OrganizerFind(offset: Int, limit: Int, name: String): [Organizer!] | |||||
OrganizerFind(offset: Int, limit: Int, ort: String, plz: Int, name: String): [Organizer!] | |||||
Event(id: UUID!): Event | Event(id: UUID!): Event | ||||
EventFind(offset: Int, limit: Int, organizer: UUID, date: Date): [Event!] | EventFind(offset: Int, limit: Int, organizer: UUID, date: Date): [Event!] | ||||
} | } | ||||
type Mutation { | type Mutation { | ||||
login(token: String, passwort: String, email: String): Person | login(token: String, passwort: String, email: String): Person | ||||
PersonRegister(passwort: String!, email: EmailAddress!, familyName: String!, givenName: String!, organizer: UUID!): Person! | |||||
ConfirmMail(confirmCode: String!, email: String!): Person | |||||
ChangePassword(newPassword: String!, oldPassword: String!): Boolean! | |||||
OrganizerRegister(ort: String, plz: Int, name: String!): Organizer! | |||||
} | } |
} | } | ||||
if (data.email && data.passwort) { | if (data.email && data.passwort) { | ||||
console.log(data); | |||||
const entries: any[] = (await Promise.all( | const entries: any[] = (await Promise.all( | ||||
(await db.fetch('person', { 'email': data.email } )) | (await db.fetch('person', { 'email': data.email } )) | ||||
.map(async (e) => ({ | .map(async (e) => ({ | ||||
authOK: await checkPassword(data.passwort, e.passwort) | authOK: await checkPassword(data.passwort, e.passwort) | ||||
})))) | })))) | ||||
.filter(e => e.authOK); | .filter(e => e.authOK); | ||||
console.log(entries); | |||||
if (entries.length !== 1) { | if (entries.length !== 1) { | ||||
return this.LoginFailed(); | return this.LoginFailed(); | ||||
} | } |
import { Field, ObjectType } from '@nestjs/graphql'; | |||||
import {Field, Int, ObjectType} from '@nestjs/graphql'; | |||||
import { UUID } from '../../global/scalars/UUID'; | import { UUID } from '../../global/scalars/UUID'; | ||||
@ObjectType() | @ObjectType() | ||||
@Field(() => String, { nullable: false }) | @Field(() => String, { nullable: false }) | ||||
name: string | name: string | ||||
@Field(() => Int, { nullable: true }) | |||||
plz?: number | |||||
@Field(() => String, { nullable: true }) | |||||
ort?: string | |||||
@Field(() => String, { nullable: true }) | @Field(() => String, { nullable: true }) | ||||
logo?: string | logo?: string | ||||
import { Organizer } from './models/Organizer'; | import { Organizer } from './models/Organizer'; | ||||
import { Client } from '../client'; | import { Client } from '../client'; | ||||
import { UUID } from '../global/scalars/UUID'; | import { UUID } from '../global/scalars/UUID'; | ||||
import { v4 as uuid } from 'uuid'; | |||||
@Injectable() | @Injectable() | ||||
export class OrganizerService { | export class OrganizerService { | ||||
return db.fetch('organizer', filter, limit, offset); | return db.fetch('organizer', filter, limit, offset); | ||||
} | } | ||||
async update(id: UUID, ops: any, filter: any, client: Client): Promise<Organizer> { | |||||
return db.doOps('organizer', id, ops, filter, client) | |||||
async update(client: Client, id: UUID, ops: any, filter?: any): Promise<Organizer> { | |||||
return db.doOps('organizer', id, ops, filter, client); | |||||
} | |||||
async create(client: Client, name: string, plz?: number, ort?: string): Promise<Organizer> { | |||||
const neu = { | |||||
_id: uuid(), | |||||
name, | |||||
plz: plz || null, | |||||
ort: ort || null, | |||||
} | |||||
return db.insert('organizer', neu, client); | |||||
} | } | ||||
} | } |
import { Args, Context, Mutation, Resolver } from '@nestjs/graphql'; | |||||
import {Args, Context, Int, Mutation, Resolver} from '@nestjs/graphql'; | |||||
import { Organizer } from '../models/Organizer'; | import { Organizer } from '../models/Organizer'; | ||||
import { Client } from '../../client'; | import { Client } from '../../client'; | ||||
import { OrganizerService } from '../organizer.service'; | import { OrganizerService } from '../organizer.service'; | ||||
constructor( | constructor( | ||||
private readonly service: OrganizerService, | private readonly service: OrganizerService, | ||||
) {} | ) {} | ||||
@Mutation(() => Organizer, { nullable: false }) | |||||
async OrganizerRegister( | |||||
@Context('client') client: Client, | |||||
@Args('name') name: string, | |||||
@Args('plz', { type: () => Int, nullable: true }) plz?: number, | |||||
@Args('ort', { nullable: true }) ort?: string, | |||||
): Promise<Organizer> { | |||||
const filter: any = {} | |||||
if (name) filter.name = name; | |||||
if (plz) filter.plz = plz; | |||||
if (ort) filter.ort = ort; | |||||
let tmp = await this.service.find(filter); | |||||
if (tmp.length === 0) | |||||
return this.service.create(client, name, plz, ort); | |||||
return tmp[0]; | |||||
} | |||||
} | } |
async OrganizerFind( | async OrganizerFind( | ||||
@Context('client') client: Client, | @Context('client') client: Client, | ||||
@Args('name', { nullable: true }) name?: string, | @Args('name', { nullable: true }) name?: string, | ||||
@Args('plz', { type: () => Int, nullable: true }) plz?: number, | |||||
@Args('ort', { nullable: true }) ort?: string, | |||||
@Args('limit', { type: () => Int, nullable: true }) limit?: number, | @Args('limit', { type: () => Int, nullable: true }) limit?: number, | ||||
@Args('offset', { type: () => Int, nullable: true }) offset?: number, | @Args('offset', { type: () => Int, nullable: true }) offset?: number, | ||||
): Promise<Organizer[]> { | ): Promise<Organizer[]> { | ||||
const filter: any = {} | const filter: any = {} | ||||
if (name) filter.name = name; | if (name) filter.name = name; | ||||
if (plz) filter.plz = plz; | |||||
if (ort) filter.ort = ort; | |||||
let tmp = await this.service.find(filter, limit, offset); | let tmp = await this.service.find(filter, limit, offset); | ||||
if (tmp.length > 1000) throw new HttpException('too many results', 413); | if (tmp.length > 1000) throw new HttpException('too many results', 413); |
import { Context, Parent, ResolveField, Resolver } from '@nestjs/graphql'; | |||||
import {Context, Int, Parent, ResolveField, Resolver} from '@nestjs/graphql'; | |||||
import { Organizer } from '../models/Organizer'; | import { Organizer } from '../models/Organizer'; | ||||
import { Client } from '../../client'; | import { Client } from '../../client'; | ||||
import { UUID } from '../../global/scalars/UUID'; | import { UUID } from '../../global/scalars/UUID'; | ||||
return parent.name; | return parent.name; | ||||
} | } | ||||
@ResolveField(() => Int, { nullable: true }) | |||||
async plz( | |||||
@Context('client') client: Client, | |||||
@Parent() parent: Organizer | |||||
): Promise<number> { | |||||
return parent.plz; | |||||
} | |||||
@ResolveField(() => String, { nullable: true }) | |||||
async ort( | |||||
@Context('client') client: Client, | |||||
@Parent() parent: Organizer | |||||
): Promise<string> { | |||||
return parent.ort; | |||||
} | |||||
@ResolveField(() => String, { nullable: true }) | @ResolveField(() => String, { nullable: true }) | ||||
async logo( | async logo( | ||||
@Context('client') client: Client, | @Context('client') client: Client, |
import { Person } from './models/Person'; | import { Person } from './models/Person'; | ||||
import { Client } from '../client'; | import { Client } from '../client'; | ||||
import { UUID } from '../global/scalars/UUID'; | import { UUID } from '../global/scalars/UUID'; | ||||
import { Organizer } from '../organizer/models/Organizer' | |||||
import { v4 as uuid } from 'uuid'; | |||||
import {EmailAddress} from '../global/scalars/EmailAddress' | |||||
import {secureHash} from '../generate' | |||||
@Injectable() | @Injectable() | ||||
export class PersonService { | export class PersonService { | ||||
return db.fetch('person', filter, limit, offset); | return db.fetch('person', filter, limit, offset); | ||||
} | } | ||||
async update(id: UUID, ops: any, filter: any, client: Client): Promise<Person> { | |||||
async update(client: Client, id: UUID, ops: any, filter?: any): Promise<Person> { | |||||
return db.doOps('person', id, ops, filter, client) | return db.doOps('person', id, ops, filter, client) | ||||
} | } | ||||
async create(client: Client, givenName: string, familyName: string, email: EmailAddress, passwort: string): Promise<Person> { | |||||
const neu = { | |||||
_id: uuid(), | |||||
givenName, | |||||
familyName, | |||||
email, | |||||
passwort: await secureHash(passwort), | |||||
confirmCode: uuid(), | |||||
} | |||||
return db.insert('person', neu, client); | |||||
} | |||||
} | } |
import { Client } from '../../client'; | import { Client } from '../../client'; | ||||
import { PersonService } from '../person.service'; | import { PersonService } from '../person.service'; | ||||
import { HttpException } from '@nestjs/common'; | import { HttpException } from '@nestjs/common'; | ||||
import {UUID} from '../../global/scalars/UUID' | |||||
import {OrganizerService} from '../../organizer/organizer.service' | |||||
import {EmailAddress} from '../../global/scalars/EmailAddress' | |||||
import {checkPassword, secureHash} from '../../generate' | |||||
@Resolver(() => Person) | @Resolver(() => Person) | ||||
export class PersonResolverM { | export class PersonResolverM { | ||||
throw new HttpException('Logindaten falsch', 403); | throw new HttpException('Logindaten falsch', 403); | ||||
} | } | ||||
return this.service.findOneById(client.getUser()?._id); | |||||
const tmp = await this.service.findOneById(client.getUser()?._id); | |||||
if (!!(tmp as unknown as any).confirmCode) { | |||||
throw new HttpException('E-Mail-Adresse noch nicht bestätigt!', 403); | |||||
} | |||||
return tmp; | |||||
} | } | ||||
/* @Mutation(() => Person, { nullable: true }) | |||||
async PersonUpdate( | |||||
@Mutation(() => Person, { nullable: false }) | |||||
async PersonRegister( | |||||
@Context('client') client: Client, | @Context('client') client: Client, | ||||
@Args('id', { type: () => UUID, nullable: false }) id: UUID, | |||||
@Args('givenName', { nullable: true }) givenName?: string, | |||||
@Args('familyName', { nullable: true }) familyName?: string, | |||||
@Args('birthDate', { type: () => Date, nullable: true }) birthDate?: Date, | |||||
@Args('organizer', { type: () => UUID, nullable: false }) organizer: UUID, | |||||
@Args('givenName', { nullable: false }) givenName: string, | |||||
@Args('familyName', { nullable: false }) familyName: string, | |||||
@Args('email', { type: () => EmailAddress, nullable: false }) email: EmailAddress, | |||||
@Args('passwort', { nullable: false }) passwort: string, | |||||
): Promise<Person> { | ): Promise<Person> { | ||||
if (!client.isMaster() && !client.isSelf(id)) return null; | |||||
const organizerService = new OrganizerService(); | |||||
const o = await organizerService.findOneById(organizer); | |||||
if (!o) { | |||||
throw new HttpException('Organizer-ID not found!', 404); | |||||
} | |||||
const tmp = await this.service.create(client, givenName, familyName, email, passwort); | |||||
const p = await this.service.findOneById(id); | |||||
if (!p) return null; | |||||
if (!o._admins) { | |||||
organizerService.update(client, o._id, {$set: {_admins: [ tmp._id ] }}, {}); | |||||
} else if (o._admins.length === 0) { | |||||
organizerService.update(client, o._id, {$push: {_admins: tmp._id }}, {}); | |||||
} else if (!o._organizers) { | |||||
organizerService.update(client, o._id, {$set: {_organizers: [ tmp._id ] }}, {}); | |||||
} else { | |||||
organizerService.update(client, o._id, {$push: {_organizers: tmp._id }}, {}); | |||||
} | |||||
// TODO: Mail verschicken | |||||
const ops: any = {$set:{}}; | |||||
return tmp; | |||||
} | |||||
if (givenName) ops['$set'].givenName = givenName; | |||||
if (familyName) ops['$set'].familyName = familyName; | |||||
if (birthDate) ops['$set'].birthDate = birthDate; | |||||
@Mutation(() => Person, { nullable: true }) | |||||
async ConfirmMail( | |||||
@Context('client') client: Client, | |||||
@Args('email') email: string, | |||||
@Args('confirmCode') confirmCode: string, | |||||
): Promise<Person> { | |||||
const tmp = await this.service.find({email, confirmCode}); | |||||
return this.service.update(id, ops, null, client); | |||||
} */ | |||||
if (tmp.length !== 1) { | |||||
throw new HttpException('confirmCode not correct', 403); | |||||
} | |||||
this.service.update(client, tmp[0]._id, { $unset: { confirmCode } }) | |||||
return tmp[0]; | |||||
} | |||||
@Mutation(() => Boolean, { nullable: false }) | |||||
async ChangePassword( | |||||
@Context('client') client: Client, | |||||
@Args('oldPassword', { nullable: false }) oldPassword: string, | |||||
@Args('newPassword', { nullable: false }) newPassword: string, | |||||
): Promise<boolean> { | |||||
if (!client.getUser()) { | |||||
throw new HttpException('you need to be logged in to change your password!', 403); | |||||
} | |||||
const tmp = await this.service.findOneById(client.getUser()._id); | |||||
if (!(await checkPassword(oldPassword, (tmp as unknown as any).passwort))) { | |||||
throw new HttpException('old password wrong!', 403); | |||||
} | |||||
this.service.update(client, tmp._id, {$set: { passwort: await secureHash(newPassword) }}); | |||||
return true; | |||||
} | |||||
} | } |