// `session.me` — returns the caller's resolved identity. This is the proof the // auth loop works end-to-end: call it with no session cookie and you get an // anonymous Subject; sign in via POST /auth/sign-in (which sets the cookie), // call it again, and `voltroPasswordStrategy` has resolved that cookie into a // `user` Subject. Browser-safe descriptor — no server imports here. import { defineAction } from '@voltro/protocol' import { Schema } from 'effect' export const me = defineAction({ name: 'session.me', // Open ON PURPOSE, and it is the one procedure in an authenticated app that // has to be: it answers "who am I", and the caller who most needs an answer // is the one who is nobody yet. A guard here would return `ScopeError` to an // anonymous browser instead of `{ type: 'anonymous' }`, and the sign-in // redirect has nothing to branch on. // // Safe because the answer is a projection of the caller's OWN request: the // Subject `voltroPasswordStrategy` resolved from the cookie they sent. It // reads no table and can say nothing about anybody else. openAccess: 'echoes the caller\'s own resolved Subject (type/id/tenantId) — reads no table and ' + 'reveals nothing the caller did not present. Anonymous callers must reach it, or ' + 'nothing can tell them to sign in.', input: Schema.Struct({}), output: Schema.Struct({ // 'anonymous' | 'user' | 'apiKey' | 'serviceAccount' type: Schema.String, // null while anonymous; the user id once signed in. id: Schema.NullOr(Schema.String), tenantId: Schema.NullOr(Schema.String), }), })