fase(9): auth module with casl rbac and session management
This commit is contained in:
21
src/modules/auth/domain/value-objects/Email.ts
Normal file
21
src/modules/auth/domain/value-objects/Email.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { ValueObject } from '../../../../shared/domain/ValueObject';
|
||||
|
||||
interface EmailProps {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export class Email extends ValueObject<EmailProps> {
|
||||
private static readonly EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
|
||||
static create(value: string): Email {
|
||||
const normalized = value.trim().toLowerCase();
|
||||
if (!Email.EMAIL_REGEX.test(normalized)) {
|
||||
throw new Error(`Invalid email address: ${value}`);
|
||||
}
|
||||
return new Email({ value: normalized });
|
||||
}
|
||||
|
||||
get value(): string {
|
||||
return this.props.value;
|
||||
}
|
||||
}
|
||||
28
src/modules/auth/domain/value-objects/Permission.ts
Normal file
28
src/modules/auth/domain/value-objects/Permission.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { ValueObject } from '../../../../shared/domain/ValueObject';
|
||||
|
||||
export type PermissionAction = 'create' | 'read' | 'update' | 'delete' | 'manage';
|
||||
export type PermissionSubject =
|
||||
| 'Session'
|
||||
| 'Finding'
|
||||
| 'Report'
|
||||
| 'Integration'
|
||||
| 'Organization'
|
||||
| 'User'
|
||||
| 'Settings'
|
||||
| 'License'
|
||||
| 'ApiKey'
|
||||
| 'all';
|
||||
|
||||
interface PermissionProps {
|
||||
action: PermissionAction;
|
||||
subject: PermissionSubject;
|
||||
}
|
||||
|
||||
export class Permission extends ValueObject<PermissionProps> {
|
||||
static create(action: PermissionAction, subject: PermissionSubject): Permission {
|
||||
return new Permission({ action, subject });
|
||||
}
|
||||
|
||||
get action(): PermissionAction { return this.props.action; }
|
||||
get subject(): PermissionSubject { return this.props.subject; }
|
||||
}
|
||||
37
src/modules/auth/domain/value-objects/Role.ts
Normal file
37
src/modules/auth/domain/value-objects/Role.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { ValueObject } from '../../../../shared/domain/ValueObject';
|
||||
|
||||
export type RoleValue = 'owner' | 'admin' | 'member' | 'viewer';
|
||||
|
||||
interface RoleProps {
|
||||
value: RoleValue;
|
||||
}
|
||||
|
||||
export class Role extends ValueObject<RoleProps> {
|
||||
static readonly OWNER: RoleValue = 'owner';
|
||||
static readonly ADMIN: RoleValue = 'admin';
|
||||
static readonly MEMBER: RoleValue = 'member';
|
||||
static readonly VIEWER: RoleValue = 'viewer';
|
||||
|
||||
private static readonly VALID_ROLES: RoleValue[] = ['owner', 'admin', 'member', 'viewer'];
|
||||
|
||||
static create(value: string): Role {
|
||||
if (!Role.VALID_ROLES.includes(value as RoleValue)) {
|
||||
throw new Error(`Invalid role: ${value}. Must be one of: ${Role.VALID_ROLES.join(', ')}`);
|
||||
}
|
||||
return new Role({ value: value as RoleValue });
|
||||
}
|
||||
|
||||
static owner(): Role { return new Role({ value: 'owner' }); }
|
||||
static admin(): Role { return new Role({ value: 'admin' }); }
|
||||
static member(): Role { return new Role({ value: 'member' }); }
|
||||
static viewer(): Role { return new Role({ value: 'viewer' }); }
|
||||
|
||||
get value(): RoleValue {
|
||||
return this.props.value;
|
||||
}
|
||||
|
||||
isOwner(): boolean { return this.props.value === 'owner'; }
|
||||
isAdmin(): boolean { return this.props.value === 'admin'; }
|
||||
isMember(): boolean { return this.props.value === 'member'; }
|
||||
isViewer(): boolean { return this.props.value === 'viewer'; }
|
||||
}
|
||||
Reference in New Issue
Block a user