@@ -8,6 +8,10 @@ type Person { | |||
familyName: String! | |||
email: EmailAddress! | |||
token: String | |||
_adminOf: [UUID!] | |||
adminOf: [Organizer!] | |||
_organizerOf: [UUID!] | |||
organizerOf: [Organizer!] | |||
} | |||
"""UUID""" | |||
@@ -18,12 +22,6 @@ A field whose value conforms to the standard internet email address format as sp | |||
""" | |||
scalar EmailAddress | |||
type Apparatus { | |||
_id: UUID! | |||
name: String! | |||
logo: String | |||
} | |||
type Organizer { | |||
_id: UUID! | |||
name: String! | |||
@@ -32,6 +30,16 @@ type Organizer { | |||
logo: String | |||
_admins: [UUID!] | |||
_organizers: [UUID!] | |||
_pending: [UUID!] | |||
admins: [Person!] | |||
organizers: [Person!] | |||
pending: [Person!] | |||
} | |||
type Apparatus { | |||
_id: UUID! | |||
name: String! | |||
logo: String | |||
} | |||
type Timeslot { |
@@ -20,6 +20,8 @@ export class Client { | |||
private token: string = null; | |||
private master: boolean = false; | |||
private adminOf: UUID[] = []; | |||
private organizerOf: UUID[] = []; | |||
constructor(id?: UUID, ip?: string) { | |||
this.id = id; | |||
@@ -85,6 +87,9 @@ export class Client { | |||
this.master = entry.master; | |||
this.adminOf = (await db.fetch('organizer', { _admins: userid })).map(e => e._id); | |||
this.organizerOf = (await db.fetch('organizer', { _organizers: userid })).map(e => e._id); | |||
return; | |||
} | |||
@@ -109,11 +114,19 @@ export class Client { | |||
return JSON.parse(Base64.decode(this.token?.split('.')?.[1] || '')); | |||
} | |||
public isSelf(id: string | UUID): boolean { | |||
public isSelf(id: UUID): boolean { | |||
return this.getUser()?._id === id; | |||
} | |||
public isMaster(): boolean { | |||
return this.master; | |||
} | |||
public isAdmin(id: UUID): boolean { | |||
return this.adminOf.indexOf(id) !== -1; | |||
} | |||
public isOrganizer(id: UUID): boolean { | |||
return this.isAdmin(id) || this.organizerOf.indexOf(id) !== -1; | |||
} | |||
} |
@@ -23,4 +23,7 @@ export class Organizer { | |||
@Field(() => [UUID], { nullable: true }) | |||
_organizers?: UUID[] | |||
@Field(() => [UUID], { nullable: true }) | |||
_pending?: UUID[] | |||
} |
@@ -2,6 +2,8 @@ import {Context, Int, Parent, ResolveField, Resolver} from '@nestjs/graphql'; | |||
import { Organizer } from '../models/Organizer'; | |||
import { Client } from '../../client'; | |||
import { UUID } from '../../global/scalars/UUID'; | |||
import {Person} from '../../person/models/Person' | |||
import {PersonService} from '../../person/person.service' | |||
@Resolver(() => Organizer) | |||
export class OrganizerResolver { | |||
@@ -50,18 +52,64 @@ export class OrganizerResolver { | |||
@Context('client') client: Client, | |||
@Parent() parent: Organizer | |||
): Promise<UUID[]> { | |||
if (!client.isMaster()) return null; | |||
if (!client.isMaster() && !client.isOrganizer(parent._id)) return null; | |||
return parent._admins; | |||
} | |||
@ResolveField(() => [Person], { nullable: true }) | |||
async admins( | |||
@Context('client') client: Client, | |||
@Parent() parent: Organizer | |||
): Promise<Person[]> { | |||
if (!client.isMaster() && !client.isOrganizer(parent._id)) return null; | |||
const personService = new PersonService(); | |||
return Promise.all((parent._admins || []).map(e => personService.findOneById(e))); | |||
} | |||
@ResolveField(() => [UUID], { nullable: true }) | |||
async _organizers( | |||
@Context('client') client: Client, | |||
@Parent() parent: Organizer | |||
): Promise<UUID[]> { | |||
if (!client.isMaster()) return null; | |||
if (!client.isMaster() && !client.isOrganizer(parent._id)) return null; | |||
return parent._organizers; | |||
} | |||
@ResolveField(() => [Person], { nullable: true }) | |||
async organizers( | |||
@Context('client') client: Client, | |||
@Parent() parent: Organizer | |||
): Promise<Person[]> { | |||
if (!client.isMaster() && !client.isOrganizer(parent._id)) return null; | |||
const personService = new PersonService(); | |||
return Promise.all((parent._organizers || []).map(e => personService.findOneById(e))); | |||
} | |||
@ResolveField(() => [UUID], { nullable: true }) | |||
async _pending( | |||
@Context('client') client: Client, | |||
@Parent() parent: Organizer | |||
): Promise<UUID[]> { | |||
if (!client.isMaster() && !client.isAdmin(parent._id)) return null; | |||
return parent._pending; | |||
} | |||
@ResolveField(() => [Person], { nullable: true }) | |||
async pending( | |||
@Context('client') client: Client, | |||
@Parent() parent: Organizer | |||
): Promise<Person[]> { | |||
if (!client.isMaster() && !client.isAdmin(parent._id)) return null; | |||
const personService = new PersonService(); | |||
return Promise.all((parent._pending || []).map(e => personService.findOneById(e))); | |||
} | |||
} |
@@ -59,10 +59,10 @@ export class PersonResolverM { | |||
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 if (!o._pending) { | |||
organizerService.update(client, o._id, {$set: {_pending: [ tmp._id ] }}, {}); | |||
} else { | |||
organizerService.update(client, o._id, {$push: {_organizers: tmp._id }}, {}); | |||
organizerService.update(client, o._id, {$push: {_pending: tmp._id }}, {}); | |||
} | |||
// TODO: Mail verschicken |
@@ -16,7 +16,7 @@ export class PersonResolverQ { | |||
@Context('client') client: Client, | |||
@Args('id') id: UUID, | |||
): Promise<Person> { | |||
if (!client.isMaster()) return null; | |||
if (!client.isMaster() && !client.isSelf(id)) return null; | |||
return await this.service.findOneById(id) as Person; | |||
} |
@@ -3,6 +3,8 @@ import { Person } from '../models/Person'; | |||
import { Client } from '../../client'; | |||
import { UUID } from '../../global/scalars/UUID'; | |||
import {EmailAddress} from '../../global/scalars/EmailAddress' | |||
import {OrganizerService} from '../../organizer/organizer.service' | |||
import {Organizer} from '../../organizer/models/Organizer' | |||
@Resolver(() => Person) | |||
export class PersonResolver { | |||
@@ -47,4 +49,54 @@ export class PersonResolver { | |||
if (!client.isMaster() && !client.isSelf(parent._id)) return null; | |||
return parent.email; | |||
} | |||
@ResolveField(() => [UUID], { nullable: true }) | |||
async _adminOf( | |||
@Context('client') client: Client, | |||
@Parent() parent: Person | |||
): Promise<UUID[]> { | |||
if (!client.isMaster() && !client.isSelf(parent._id)) return null; | |||
const organizerService = new OrganizerService(); | |||
const o = await organizerService.find({ _admins: client.getUser()._id }); | |||
return o.map(e => e._id); | |||
} | |||
@ResolveField(() => [Organizer], { nullable: true }) | |||
async adminOf( | |||
@Context('client') client: Client, | |||
@Parent() parent: Person | |||
): Promise<Organizer[]> { | |||
if (!client.isMaster() && !client.isSelf(parent._id)) return null; | |||
const organizerService = new OrganizerService(); | |||
return organizerService.find({ _admins: client.getUser()._id }); | |||
} | |||
@ResolveField(() => [UUID], { nullable: true }) | |||
async _organizerOf( | |||
@Context('client') client: Client, | |||
@Parent() parent: Person | |||
): Promise<UUID[]> { | |||
if (!client.isMaster() && !client.isSelf(parent._id)) return null; | |||
const organizerService = new OrganizerService(); | |||
const o = await organizerService.find({ $or: [{_organizers: client.getUser()._id}] }); | |||
return o.map(e => e._id); | |||
} | |||
@ResolveField(() => [Organizer], { nullable: true }) | |||
async organizerOf( | |||
@Context('client') client: Client, | |||
@Parent() parent: Person | |||
): Promise<Organizer[]> { | |||
if (!client.isMaster() && !client.isSelf(parent._id)) return null; | |||
const organizerService = new OrganizerService(); | |||
return await organizerService.find({ $or: [{_organizers: client.getUser()._id}] }); | |||
} | |||
} |