Browse Source

Registrierung, Bestätigen, Passwort ändern

tags/v0.9.1
akimmig 4 years ago
parent
commit
fcd10f77ef
9 changed files with 160 additions and 25 deletions
  1. +7
    -1
      server/schema.gql
  2. +0
    -2
      server/src/client.ts
  3. +7
    -1
      server/src/organizer/models/Organizer.ts
  4. +14
    -2
      server/src/organizer/organizer.service.ts
  5. +20
    -1
      server/src/organizer/resolver/organizer.mutation.ts
  6. +4
    -0
      server/src/organizer/resolver/organizer.query.ts
  7. +17
    -1
      server/src/organizer/resolver/organizer.ts
  8. +18
    -1
      server/src/person/person.service.ts
  9. +73
    -16
      server/src/person/resolver/person.mutation.ts

+ 7
- 1
server/schema.gql View File

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!
} }

+ 0
- 2
server/src/client.ts View File

} }


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();
} }

+ 7
- 1
server/src/organizer/models/Organizer.ts View File

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



+ 14
- 2
server/src/organizer/organizer.service.ts View File

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);
} }
} }

+ 20
- 1
server/src/organizer/resolver/organizer.mutation.ts View File

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];
}
} }

+ 4
- 0
server/src/organizer/resolver/organizer.query.ts View File

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);

+ 17
- 1
server/src/organizer/resolver/organizer.ts View File

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,

+ 18
- 1
server/src/person/person.service.ts View File

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);
}
} }

+ 73
- 16
server/src/person/resolver/person.mutation.ts View File

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;
}
} }

Loading…
Cancel
Save