51 lines
1.7 KiB
TypeScript
51 lines
1.7 KiB
TypeScript
|
|
import type { IdentityContext } from "@metis/identity/module";
|
||
|
|
import type { RelationshipContext, RelationshipReadAccess } from "@metis/relationship-contracts";
|
||
|
|
import { RelationshipContextSchema, RelationshipReadError } from "@metis/relationship-contracts";
|
||
|
|
import { Result } from "@repo/rdx-utils";
|
||
|
|
|
||
|
|
/** Contextos emitidos desde sesión; copiar sus campos no produce una credencial válida. */
|
||
|
|
export class SessionRelationshipReadAccess implements RelationshipReadAccess {
|
||
|
|
private readonly sessions = new WeakMap<RelationshipContext, IdentityContext>();
|
||
|
|
|
||
|
|
constructor(
|
||
|
|
private readonly isAuthenticated: (session: IdentityContext) => Promise<boolean>,
|
||
|
|
private readonly companyExists: (companyId: string) => Promise<boolean>
|
||
|
|
) {}
|
||
|
|
|
||
|
|
async createContext(session: IdentityContext, companyId: string, requestId: string) {
|
||
|
|
const parsed = RelationshipContextSchema.safeParse({
|
||
|
|
operatorId: session.userId,
|
||
|
|
companyId,
|
||
|
|
requestId,
|
||
|
|
});
|
||
|
|
|
||
|
|
if (
|
||
|
|
!(
|
||
|
|
parsed.success &&
|
||
|
|
(await this.isAuthenticated(session)) &&
|
||
|
|
(await this.companyExists(parsed.data.companyId))
|
||
|
|
)
|
||
|
|
) {
|
||
|
|
return Result.fail(new RelationshipReadError("FORBIDDEN"));
|
||
|
|
}
|
||
|
|
this.sessions.set(parsed.data, Object.freeze({ ...session }));
|
||
|
|
|
||
|
|
return Result.ok(parsed.data);
|
||
|
|
}
|
||
|
|
|
||
|
|
async authorize(context: RelationshipContext): Promise<Result<true, RelationshipReadError>> {
|
||
|
|
const session = this.sessions.get(context);
|
||
|
|
|
||
|
|
if (
|
||
|
|
!session ||
|
||
|
|
session.userId !== context.operatorId ||
|
||
|
|
!(await this.isAuthenticated(session)) ||
|
||
|
|
!(await this.companyExists(context.companyId))
|
||
|
|
) {
|
||
|
|
return Result.fail(new RelationshipReadError("FORBIDDEN"));
|
||
|
|
}
|
||
|
|
|
||
|
|
return Result.ok(true);
|
||
|
|
}
|
||
|
|
}
|