57 lines
1.4 KiB
TypeScript
57 lines
1.4 KiB
TypeScript
import { VersionedAggregateRoot } from '@task-stream/api/shared/domain';
|
|
import { UserDeactivatedEvent } from './events/user-deactivated.event';
|
|
|
|
export interface UserSnapshot {
|
|
/** Pireon user id (string to stay provider-agnostic). */
|
|
id: string;
|
|
name: string;
|
|
email: string;
|
|
isActive: boolean;
|
|
/** Global roles in the identity server. */
|
|
roles: string[];
|
|
/** Roles granted inside this OAuth client (task-stream). */
|
|
appRoles: string[];
|
|
}
|
|
|
|
/**
|
|
* A person managed by the Pireon identity server. Not event-sourced here
|
|
* (Pireon owns users): UserFactory rebuilds it from Pireon or the local cache.
|
|
*/
|
|
export class User extends VersionedAggregateRoot implements UserSnapshot {
|
|
public name!: string;
|
|
public email!: string;
|
|
public isActive = true;
|
|
public roles: string[] = [];
|
|
public appRoles: string[] = [];
|
|
|
|
constructor(id: string) {
|
|
super();
|
|
this.id = id;
|
|
}
|
|
|
|
/** Global Pireon admins implicitly hold every app role. */
|
|
hasAppRole(role: string): boolean {
|
|
return this.appRoles.includes(role) || this.roles.includes('admin');
|
|
}
|
|
|
|
deactivate(): void {
|
|
if (!this.isActive) return;
|
|
this.apply(new UserDeactivatedEvent(this.id));
|
|
}
|
|
|
|
onUserDeactivatedEvent(): void {
|
|
this.isActive = false;
|
|
}
|
|
|
|
toSnapshot(): UserSnapshot {
|
|
return {
|
|
id: this.id,
|
|
name: this.name,
|
|
email: this.email,
|
|
isActive: this.isActive,
|
|
roles: [...this.roles],
|
|
appRoles: [...this.appRoles],
|
|
};
|
|
}
|
|
}
|