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

@@ -27,6 +27,8 @@ type Apparatus {
type Organizer {
_id: UUID!
name: String!
plz: Int
ort: String
logo: String
_admins: [UUID!]
_organizers: [UUID!]
@@ -56,11 +58,15 @@ type Query {
Apparatus(id: UUID!): Apparatus
ApparatusFind(offset: Int, limit: Int, name: String): [Apparatus!]
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
EventFind(offset: Int, limit: Int, organizer: UUID, date: Date): [Event!]
}

type Mutation {
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

@@ -45,7 +45,6 @@ export class Client {
}

if (data.email && data.passwort) {
console.log(data);
const entries: any[] = (await Promise.all(
(await db.fetch('person', { 'email': data.email } ))
.map(async (e) => ({
@@ -53,7 +52,6 @@ export class Client {
authOK: await checkPassword(data.passwort, e.passwort)
}))))
.filter(e => e.authOK);
console.log(entries);
if (entries.length !== 1) {
return this.LoginFailed();
}

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

@@ -1,4 +1,4 @@
import { Field, ObjectType } from '@nestjs/graphql';
import {Field, Int, ObjectType} from '@nestjs/graphql';
import { UUID } from '../../global/scalars/UUID';

@ObjectType()
@@ -9,6 +9,12 @@ export class Organizer {
@Field(() => String, { nullable: false })
name: string

@Field(() => Int, { nullable: true })
plz?: number

@Field(() => String, { nullable: true })
ort?: string

@Field(() => String, { nullable: true })
logo?: string


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

@@ -3,6 +3,7 @@ import { db } from '../db';
import { Organizer } from './models/Organizer';
import { Client } from '../client';
import { UUID } from '../global/scalars/UUID';
import { v4 as uuid } from 'uuid';

@Injectable()
export class OrganizerService {
@@ -16,7 +17,18 @@ export class OrganizerService {
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

@@ -1,4 +1,4 @@
import { Args, Context, Mutation, Resolver } from '@nestjs/graphql';
import {Args, Context, Int, Mutation, Resolver} from '@nestjs/graphql';
import { Organizer } from '../models/Organizer';
import { Client } from '../../client';
import { OrganizerService } from '../organizer.service';
@@ -9,4 +9,23 @@ export class OrganizerResolverM {
constructor(
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

@@ -23,12 +23,16 @@ export class OrganizerResolverQ {
async OrganizerFind(
@Context('client') client: Client,
@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('offset', { type: () => Int, nullable: true }) offset?: number,
): 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, limit, offset);
if (tmp.length > 1000) throw new HttpException('too many results', 413);

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

@@ -1,4 +1,4 @@
import { Context, Parent, ResolveField, Resolver } from '@nestjs/graphql';
import {Context, Int, Parent, ResolveField, Resolver} from '@nestjs/graphql';
import { Organizer } from '../models/Organizer';
import { Client } from '../../client';
import { UUID } from '../../global/scalars/UUID';
@@ -21,6 +21,22 @@ export class OrganizerResolver {
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 })
async logo(
@Context('client') client: Client,

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

@@ -3,6 +3,10 @@ import { db } from '../db';
import { Person } from './models/Person';
import { Client } from '../client';
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()
export class PersonService {
@@ -16,7 +20,20 @@ export class PersonService {
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)
}

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

@@ -3,6 +3,10 @@ import { Person } from '../models/Person';
import { Client } from '../../client';
import { PersonService } from '../person.service';
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)
export class PersonResolverM {
@@ -24,28 +28,81 @@ export class PersonResolverM {
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,
@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> {
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