@shivaedev/identity 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +18 -10
  2. package/dist/middleware.d.ts +5 -4
  3. package/dist/middleware.d.ts.map +1 -1
  4. package/dist/middleware.js +7 -4
  5. package/dist/middleware.js.map +1 -1
  6. package/dist/permission.d.ts +2 -1
  7. package/dist/permission.d.ts.map +1 -1
  8. package/dist/permission.js +2 -1
  9. package/dist/permission.js.map +1 -1
  10. package/dist/server/adapters/betterAuthSessions.d.ts.map +1 -1
  11. package/dist/server/adapters/betterAuthSessions.js +2 -1
  12. package/dist/server/adapters/betterAuthSessions.js.map +1 -1
  13. package/dist/server/better-auth/mountRoutes.d.ts.map +1 -1
  14. package/dist/server/better-auth/mountRoutes.js +2 -1
  15. package/dist/server/better-auth/mountRoutes.js.map +1 -1
  16. package/dist/server/better-auth/sweepExpiredSessions.d.ts +4 -0
  17. package/dist/server/better-auth/sweepExpiredSessions.d.ts.map +1 -0
  18. package/dist/server/better-auth/sweepExpiredSessions.js +12 -0
  19. package/dist/server/better-auth/sweepExpiredSessions.js.map +1 -0
  20. package/dist/server/better-auth/testDatabase.d.ts +1 -1
  21. package/dist/server/better-auth/testDatabase.d.ts.map +1 -1
  22. package/dist/server/better-auth/testDatabase.js +2 -2
  23. package/dist/server/better-auth/testDatabase.js.map +1 -1
  24. package/dist/server/commandChanges.d.ts +0 -1
  25. package/dist/server/commandChanges.d.ts.map +1 -1
  26. package/dist/server/commandChanges.js +6 -7
  27. package/dist/server/commandChanges.js.map +1 -1
  28. package/dist/server/local.d.ts.map +1 -1
  29. package/dist/server/local.js +3 -2
  30. package/dist/server/local.js.map +1 -1
  31. package/dist/server/permissions.d.ts.map +1 -1
  32. package/dist/server/permissions.js +9 -3
  33. package/dist/server/permissions.js.map +1 -1
  34. package/dist/server/session.d.ts.map +1 -1
  35. package/dist/server/session.js +8 -7
  36. package/dist/server/session.js.map +1 -1
  37. package/dist/server/sessionKeys.d.ts +8 -4
  38. package/dist/server/sessionKeys.d.ts.map +1 -1
  39. package/dist/server/sessionKeys.js +11 -7
  40. package/dist/server/sessionKeys.js.map +1 -1
  41. package/package.json +9 -8
  42. package/src/middleware.ts +7 -4
  43. package/src/permission.ts +2 -1
  44. package/src/server/adapters/betterAuthSessions.ts +2 -1
  45. package/src/server/better-auth/mountRoutes.ts +8 -1
  46. package/src/server/better-auth/sweepExpiredSessions.ts +13 -0
  47. package/src/server/better-auth/testDatabase.ts +7 -3
  48. package/src/server/commandChanges.ts +6 -8
  49. package/src/server/local.ts +3 -2
  50. package/src/server/permissions.ts +15 -7
  51. package/src/server/session.ts +8 -7
  52. package/src/server/sessionKeys.ts +12 -8
package/README.md CHANGED
@@ -365,8 +365,8 @@ import { resolveChanges } from "@shivaedev/identity/server/sessionKeys.ts";
365
365
  const changesRpc = Api.requests.get("preferences.$changes")!;
366
366
  const handlers = Api.toLayer({
367
367
  "preferences.$changes": ({ queries }) => Stream.unwrap(
368
- Effect.map(resolveChanges(changesRpc, queries), ({ keys, context }) =>
369
- changes.stream(keys, context)
368
+ Effect.map(resolveChanges(changesRpc, queries), ({ subscription, context }) =>
369
+ changes.subscribe(subscription, context)
370
370
  )
371
371
  ),
372
372
  "preferences.get": getPreference,
@@ -374,26 +374,27 @@ const handlers = Api.toLayer({
374
374
  });
375
375
  ```
376
376
 
377
- Here `changes` is the application's `makeLiveServer` service. Keep `resolveChanges` in the invocation; resolving it while building a shared Layer would lose request identity. Pass both returned arguments to `changes.stream`.
377
+ Here `changes` is the application's `makeLiveServer` service. Keep `resolveChanges` in the invocation; resolving it while building a shared Layer would lose request identity. Pass the authorized subscription and context to `changes.subscribe`; it uses the query scopes to identify affected references and rechecks the same policies before hints leave.
378
378
 
379
- Custom authentication middleware supplies the same boundary by validating the transport session, then wrapping scoped commands with `sessionCommandChanges` before providing `Identity`:
379
+ Custom authentication middleware supplies the same boundary by validating the transport session, then wrapping scoped commands with `commandChanges` before providing `Identity`:
380
380
 
381
381
  ```ts
382
- import { Effect, Layer } from "effect";
382
+ import { Effect, Layer, Option } from "effect";
383
+ import { authorizeReads } from "@shivaedev/contract/readPolicy.ts";
383
384
  import { Identity } from "@shivaedev/identity/identity.ts";
384
- import { sessionCommandChanges } from "@shivaedev/identity/server/commandChanges.ts";
385
+ import { commandChanges } from "@shivaedev/identity/server/commandChanges.ts";
385
386
 
386
387
  const authentication = Layer.succeed(MyAuthentication, (effect, { headers, rpc, payload }) =>
387
388
  Effect.gen(function* () {
388
389
  const session = yield* requireTransportSession(headers, rpc);
389
- return yield* sessionCommandChanges(effect, rpc, payload).pipe(
390
+ return yield* authorizeReads(commandChanges(effect, rpc, payload), { rpc, payload }, Option.some({ id: session.user.id })).pipe(
390
391
  Effect.provideService(Identity, { id: session.user.id })
391
392
  );
392
393
  })
393
394
  );
394
395
  ```
395
396
 
396
- `MyAuthentication` declares `provides: Identity` and its authentication errors. `requireTransportSession` is the application's session validation; use `transportHeaders` or `resolveSession` to read HTTP or WebSocket transport credentials. The identity comes from that validated session on each invocation. `requestTracingLayer` publishes only unscoped contract invalidations; custom auth middleware must apply `sessionCommandChanges` for scoped commands. If a transaction explicitly announces scoped dependencies, use `invalidationKeys(keys, { scope: identity.id })` with `invalidateOnCommit` inside `transact` so automatic command invalidation can deduplicate the same physical keys.
397
+ `MyAuthentication` declares `provides: Identity`, its authentication errors and `MissingReadPolicy` and `QueryReadDenied` from `@shivaedev/contract/readPolicyErrors.ts`. Query policies receive the session viewer through `authorizeReads`. `requireTransportSession` is the application's session validation; use `transportHeaders` or `resolveSession` to read HTTP or WebSocket transport credentials. The identity comes from that validated session on each invocation. `requestTracingLayer` publishes only unscoped contract invalidations; custom auth middleware must apply `commandChanges` for scoped commands. If a transaction explicitly announces scoped dependencies, use `invalidationKeys(keys, { scope: identity.id })` with `invalidateOnCommit` inside `transact` so automatic command invalidation can deduplicate the same physical keys.
397
398
 
398
399
  ### Session freshness in streams
399
400
 
@@ -427,7 +428,7 @@ Caller-chosen request ids are correlation data. Keep authorization tied to the a
427
428
 
428
429
  Use `testUtils()` from `better-auth/plugins` in a test-only Better Auth instance with the host's database, secret and cookie policy. Keep the plugin out of production auth options.
429
430
 
430
- Use `authTestDatabase(pool)` from `@shivaedev/identity/server/better-auth/testDatabase.ts` when a story needs observations or faults in the default Better Auth PostgreSQL schema. It returns Effect readouts `users` (IDs and emails) and `sessions` (IDs, user IDs and emails), plus the test-only faults `expireSessions` and `omitImageColumn`. It never returns tokens, password hashes or provider credentials. These fixtures assume the default table and column mappings and operate on the supplied pool; use only an isolated test database. Application stories keep their auth SQL in this provider-owned boundary.
431
+ Use `authTestDatabase(pool)` from `@shivaedev/identity/server/better-auth/testDatabase.ts` when a story needs observations or faults in the default Better Auth PostgreSQL schema. It returns Effect readouts `users` (IDs and emails) and `sessions` (IDs, user IDs and emails), plus the test-only faults `expireSessions(userId?)` and `omitImageColumn`. Pass a user id to expire only that user's sessions, or call `expireSessions()` to expire every session. It never returns tokens, password hashes or provider credentials. These fixtures assume the default table and column mappings and operate on the supplied pool; use only an isolated test database. Application stories keep their auth SQL in this provider-owned boundary.
431
432
 
432
433
  ```ts
433
434
  import { betterAuth } from "better-auth";
@@ -481,6 +482,12 @@ app.it("the member's provider account stores no credentials", [member], function
481
482
 
482
483
  With database-backed sessions and cookie caching disabled, revocation rejects that same minted session on the next protected HTTP or RPC request. Cookie caching and secondary storage can change revocation timing.
483
484
 
485
+ ### Sweep expired sessions in a worker
486
+
487
+ Better Auth removes an expired session when it is presented. Use `sweepExpiredSessions` from `@shivaedev/identity/server/better-auth/sweepExpiredSessions.ts` to remove expired rows that are never presented again. The Effect reads the application's `SqlClient`, deletes sessions whose `expiresAt` is at or before PostgreSQL's current time, and returns the number removed. It preserves live sessions and needs no Better Auth mount or auth pool. It assumes the default Better Auth PostgreSQL table and column mappings.
488
+
489
+ Register the Effect with a worker schedule, as the starter does at midnight UTC. SQL and result-decoding failures stay in the Effect's error channel.
490
+
484
491
  ### API
485
492
 
486
493
  Import the module that defines the name; there is no package-root entry. Paths below follow `@shivaedev/identity/`.
@@ -503,12 +510,13 @@ Import the module that defines the name; there is no package-root entry. Paths b
503
510
  | `server/better-auth/signInGate.ts` | `SignInPolicy`: the `accounts`, `rule` and `recheckInterval` of a sign-in policy. |
504
511
  | `server/better-auth/revokeUnadmitted.ts` | `RevokedSessions`: the `{ users, sessions }` counts of a revocation. |
505
512
  | `server/better-auth/userProfiles.ts` | Public profile lookups for other users. |
513
+ | `server/better-auth/sweepExpiredSessions.ts` | `sweepExpiredSessions`: delete expired sessions through the application's SQL client and return the number removed. |
506
514
  | `server/better-auth/testDatabase.ts` | `authTestDatabase(pool)`: test-only identity/session readouts and faults for the default PostgreSQL auth schema. |
507
515
  | `server/better-auth/testing.ts` | `signedInUser(auth, fields)`, `storedProviderAccounts(auth, userId)`: test-only minted user sessions and credential storage observations. |
508
516
 
509
517
  ### Install, setup and limits
510
518
 
511
- Install `@shivaedev/identity` with `effect` as its peer. Everything outside `server/better-auth/` works with only `effect` installed, including the Promise-based `betterAuthSessions` adapter. `server/better-auth/` needs the optional peers `better-auth` and `pg`. Browser code imports only `identity.ts`, `middleware.ts` and `permission.ts`.
519
+ Install `@shivaedev/identity` with `effect` as its peer. Everything outside `server/better-auth/` works with only `effect` installed, including the Promise-based `betterAuthSessions` adapter. Better Auth mounts and test fixtures need the optional peers `better-auth` and `pg`; `sweepExpiredSessions` needs only the application's Effect SQL client. Browser code imports only `identity.ts`, `middleware.ts` and `permission.ts`.
512
520
 
513
521
  - The package needs Node 24 or newer.
514
522
  - Keep the auth provider's configuration, cookie settings and resource authorization in the application. The session adapter takes a session lookup and an optional provider-account lookup and returns a session result; it does not write provider refresh cookies into RPC responses.
@@ -1,20 +1,21 @@
1
1
  import { Schema } from "effect";
2
2
  import { RpcMiddleware } from "effect/rpc";
3
+ import { MissingReadPolicy, QueryReadDenied } from "@shivaedev/contract/readPolicyErrors.ts";
3
4
  import { AuthUnavailable, Forbidden, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
4
5
  import type { Identity, OptionalIdentity, RequestId, SessionUser, SessionUserWithProviderAccounts } from "./identity.ts";
5
6
  declare const RequestTracing_base: RpcMiddleware.ServiceClass<RequestTracing, "@shivaedev/identity/RequestTracing", RequestId, Schema.Never, never, never, false>;
6
7
  export declare class RequestTracing extends RequestTracing_base {
7
8
  }
8
- declare const Authenticated_base: RpcMiddleware.ServiceClass<Authenticated, "@shivaedev/identity/Authenticated", Identity, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden]>, never, never, false>;
9
+ declare const Authenticated_base: RpcMiddleware.ServiceClass<Authenticated, "@shivaedev/identity/Authenticated", Identity, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden, typeof MissingReadPolicy, typeof QueryReadDenied]>, never, never, false>;
9
10
  export declare class Authenticated extends Authenticated_base {
10
11
  }
11
- declare const MaybeAuthenticated_base: RpcMiddleware.ServiceClass<MaybeAuthenticated, "@shivaedev/identity/MaybeAuthenticated", OptionalIdentity, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden]>, never, never, false>;
12
+ declare const MaybeAuthenticated_base: RpcMiddleware.ServiceClass<MaybeAuthenticated, "@shivaedev/identity/MaybeAuthenticated", OptionalIdentity, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden, typeof MissingReadPolicy, typeof QueryReadDenied]>, never, never, false>;
12
13
  export declare class MaybeAuthenticated extends MaybeAuthenticated_base {
13
14
  }
14
- declare const AuthenticatedUser_base: RpcMiddleware.ServiceClass<AuthenticatedUser, "@shivaedev/identity/AuthenticatedUser", Identity | SessionUser, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden]>, never, never, false>;
15
+ declare const AuthenticatedUser_base: RpcMiddleware.ServiceClass<AuthenticatedUser, "@shivaedev/identity/AuthenticatedUser", Identity | SessionUser, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden, typeof MissingReadPolicy, typeof QueryReadDenied]>, never, never, false>;
15
16
  export declare class AuthenticatedUser extends AuthenticatedUser_base {
16
17
  }
17
- declare const AuthenticatedUserWithProviderAccounts_base: RpcMiddleware.ServiceClass<AuthenticatedUserWithProviderAccounts, "@shivaedev/identity/AuthenticatedUserWithProviderAccounts", Identity | SessionUser | SessionUserWithProviderAccounts, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden]>, never, never, false>;
18
+ declare const AuthenticatedUserWithProviderAccounts_base: RpcMiddleware.ServiceClass<AuthenticatedUserWithProviderAccounts, "@shivaedev/identity/AuthenticatedUserWithProviderAccounts", Identity | SessionUser | SessionUserWithProviderAccounts, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden, typeof MissingReadPolicy, typeof QueryReadDenied]>, never, never, false>;
18
19
  export declare class AuthenticatedUserWithProviderAccounts extends AuthenticatedUserWithProviderAccounts_base {
19
20
  }
20
21
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;;AACzH,qBAAa,cAAe,SAAQ,mBAKK;CAAG;;AAC5C,qBAAa,aAAc,SAAQ,kBAOjC;CAAG;;AACL,qBAAa,kBAAmB,SAAQ,uBAK0E;CAAG;;AACrH,qBAAa,iBAAkB,SAAQ,sBAOrC;CAAG;;AACL,qBAAa,qCAAsC,SAAQ,0CAKzD;CAAG"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC7F,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;;AACzH,qBAAa,cAAe,SAAQ,mBAKK;CAAG;;AAC5C,qBAAa,aAAc,SAAQ,kBAOjC;CAAG;;AACL,qBAAa,kBAAmB,SAAQ,uBAOtC;CAAG;;AACL,qBAAa,iBAAkB,SAAQ,sBAOrC;CAAG;;AACL,qBAAa,qCAAsC,SAAQ,0CAKzD;CAAG"}
@@ -1,20 +1,23 @@
1
1
  import { Schema } from "effect";
2
2
  import { RpcMiddleware } from "effect/rpc";
3
+ import { MissingReadPolicy, QueryReadDenied } from "@shivaedev/contract/readPolicyErrors.ts";
3
4
  import { AuthUnavailable, Forbidden, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
4
5
  export class RequestTracing extends RpcMiddleware.Service()("@shivaedev/identity/RequestTracing") {
5
6
  }
6
7
  export class Authenticated extends RpcMiddleware.Service()("@shivaedev/identity/Authenticated", {
7
- error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]),
8
+ error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden, MissingReadPolicy, QueryReadDenied]),
8
9
  }) {
9
10
  }
10
- export class MaybeAuthenticated extends RpcMiddleware.Service()("@shivaedev/identity/MaybeAuthenticated", { error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]) }) {
11
+ export class MaybeAuthenticated extends RpcMiddleware.Service()("@shivaedev/identity/MaybeAuthenticated", {
12
+ error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden, MissingReadPolicy, QueryReadDenied]),
13
+ }) {
11
14
  }
12
15
  export class AuthenticatedUser extends RpcMiddleware.Service()("@shivaedev/identity/AuthenticatedUser", {
13
- error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]),
16
+ error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden, MissingReadPolicy, QueryReadDenied]),
14
17
  }) {
15
18
  }
16
19
  export class AuthenticatedUserWithProviderAccounts extends RpcMiddleware.Service()("@shivaedev/identity/AuthenticatedUserWithProviderAccounts", {
17
- error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]),
20
+ error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden, MissingReadPolicy, QueryReadDenied]),
18
21
  }) {
19
22
  }
20
23
  //# sourceMappingURL=middleware.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAEzF,MAAM,OAAO,cAAe,SAAQ,aAAa,CAAC,OAAO,EAKtD,CAAC,oCAAoC,CAAC;CAAG;AAC5C,MAAM,OAAO,aAAc,SAAQ,aAAa,CAAC,OAAO,EAKrD,CAAC,mCAAmC,EAAE;IACxC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;CAC/D,CAAC;CAAG;AACL,MAAM,OAAO,kBAAmB,SAAQ,aAAa,CAAC,OAAO,EAK1D,CAAC,wCAAwC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;CAAG;AACrH,MAAM,OAAO,iBAAkB,SAAQ,aAAa,CAAC,OAAO,EAKzD,CAAC,uCAAuC,EAAE;IAC5C,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;CAC/D,CAAC;CAAG;AACL,MAAM,OAAO,qCAAsC,SAAQ,aAAa,CAAC,OAAO,EAG7E,CAAC,2DAA2D,EAAE;IAChE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;CAC/D,CAAC;CAAG"}
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC7F,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAEzF,MAAM,OAAO,cAAe,SAAQ,aAAa,CAAC,OAAO,EAKtD,CAAC,oCAAoC,CAAC;CAAG;AAC5C,MAAM,OAAO,aAAc,SAAQ,aAAa,CAAC,OAAO,EAKrD,CAAC,mCAAmC,EAAE;IACxC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;CACnG,CAAC;CAAG;AACL,MAAM,OAAO,kBAAmB,SAAQ,aAAa,CAAC,OAAO,EAK1D,CAAC,wCAAwC,EAAE;IAC7C,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;CACnG,CAAC;CAAG;AACL,MAAM,OAAO,iBAAkB,SAAQ,aAAa,CAAC,OAAO,EAKzD,CAAC,uCAAuC,EAAE;IAC5C,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;CACnG,CAAC;CAAG;AACL,MAAM,OAAO,qCAAsC,SAAQ,aAAa,CAAC,OAAO,EAG7E,CAAC,2DAA2D,EAAE;IAChE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;CACnG,CAAC;CAAG"}
@@ -1,9 +1,10 @@
1
1
  import { Effect, Schema } from "effect";
2
2
  import { RpcMiddleware } from "effect/rpc";
3
3
  import type { Permission } from "@shivaedev/access/permission.ts";
4
+ import { MissingReadPolicy, QueryReadDenied } from "@shivaedev/contract/readPolicyErrors.ts";
4
5
  import { AuthUnavailable, Forbidden, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
5
6
  import { type Identity, SessionUser, type SessionUserValue } from "./identity.ts";
6
- export declare function permissionMiddleware<TSelf>(): <const TName extends string>(name: TName, permission: Permission) => RpcMiddleware.ServiceClass<TSelf, TName, Identity | SessionUser, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden]>, never, never, false> & {
7
+ export declare function permissionMiddleware<TSelf>(): <const TName extends string>(name: TName, permission: Permission) => RpcMiddleware.ServiceClass<TSelf, TName, Identity | SessionUser, Schema.Union<readonly [typeof Unauthorized, typeof AuthUnavailable, typeof Forbidden, typeof MissingReadPolicy, typeof QueryReadDenied]>, never, never, false> & {
7
8
  permission: Permission;
8
9
  };
9
10
  export declare function hasPermission(user: Pick<SessionUserValue, "id" | "permissions">, permission: Permission): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,EAAE,KAAK,QAAQ,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIlF,wBAAgB,oBAAoB,CAAC,KAAK,MACjC,KAAK,CAAC,KAAK,SAAS,MAAM,QAAQ,KAAK,cAAc,UAAU;;EAEvE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,GAAG,aAAa,CAAC,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAEjH;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,2DAMvD"}
1
+ {"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC7F,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,EAAE,KAAK,QAAQ,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIlF,wBAAgB,oBAAoB,CAAC,KAAK,MACjC,KAAK,CAAC,KAAK,SAAS,MAAM,QAAQ,KAAK,cAAc,UAAU;;EAEvE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,GAAG,aAAa,CAAC,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAEjH;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,2DAMvD"}
@@ -1,8 +1,9 @@
1
1
  import { Effect, Schema } from "effect";
2
2
  import { RpcMiddleware } from "effect/rpc";
3
+ import { MissingReadPolicy, QueryReadDenied } from "@shivaedev/contract/readPolicyErrors.ts";
3
4
  import { AuthUnavailable, Forbidden, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
4
5
  import { SessionUser } from "./identity.js";
5
- const Failures = Schema.Union([Unauthorized, AuthUnavailable, Forbidden]);
6
+ const Failures = Schema.Union([Unauthorized, AuthUnavailable, Forbidden, MissingReadPolicy, QueryReadDenied]);
6
7
  export function permissionMiddleware() {
7
8
  return (name, permission) => Object.assign(RpcMiddleware.Service()(name, { error: Failures }), { permission });
8
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"permission.js","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,EAAiB,WAAW,EAAyB,MAAM,eAAe,CAAC;AAElF,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC;AAE1E,MAAM,UAAU,oBAAoB;IACnC,OAAO,CAA6B,IAAW,EAAE,UAAsB,EAAE,EAAE,CAC1E,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,EAA+C,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;AACjI,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAkD,EAAE,UAAsB;IACvG,OAAO,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC;AAC7H,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,UAAsB;IACvD,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAC3C,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC;QAC9B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;QACtB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,wBAAwB,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC,CAC9G,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"permission.js","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC7F,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,EAAiB,WAAW,EAAyB,MAAM,eAAe,CAAC;AAElF,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC,CAAC;AAE9G,MAAM,UAAU,oBAAoB;IACnC,OAAO,CAA6B,IAAW,EAAE,UAAsB,EAAE,EAAE,CAC1E,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,EAA+C,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;AACjI,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAkD,EAAE,UAAsB;IACvG,OAAO,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC;AAC7H,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,UAAsB;IACvD,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAC3C,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC;QAC9B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;QACtB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,wBAAwB,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC,CAC9G,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"betterAuthSessions.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/betterAuthSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,QAAQ,CAAC;AAGnD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxE,MAAM,MAAM,UAAU,CAAC,QAAQ,SAAS,YAAY,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAClH,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,KAAK,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC,CAAC;AAC5G,MAAM,MAAM,2BAA2B,CAAC,QAAQ,SAAS,YAAY,IAAI,QAAQ,GAAG;IACnF,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG;QAAE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,oBAAoB,EAAE,EAAE,eAAe,GAAG,YAAY,CAAC,CAAA;KAAE,CAAC;CAChJ,CAAC;AAOF,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,YAAY,EAAE,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;AAC/H,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,YAAY,EAC/D,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC,EAChC,mBAAmB,EAAE,mBAAmB,GACtC,eAAe,CAAC,2BAA2B,CAAC,QAAQ,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"betterAuthSessions.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/betterAuthSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,QAAQ,CAAC;AAInD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxE,MAAM,MAAM,UAAU,CAAC,QAAQ,SAAS,YAAY,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAClH,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,KAAK,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC,CAAC;AAC5G,MAAM,MAAM,2BAA2B,CAAC,QAAQ,SAAS,YAAY,IAAI,QAAQ,GAAG;IACnF,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG;QAAE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,oBAAoB,EAAE,EAAE,eAAe,GAAG,YAAY,CAAC,CAAA;KAAE,CAAC;CAChJ,CAAC;AAOF,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,YAAY,EAAE,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;AAC/H,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,YAAY,EAC/D,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC,EAChC,mBAAmB,EAAE,mBAAmB,GACtC,eAAe,CAAC,2BAA2B,CAAC,QAAQ,CAAC,CAAC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { Effect, Option, Predicate } from "effect";
2
+ import * as HttpStatus from "effect/http/HttpStatus";
2
3
  import { redact } from "@shivaedev/errors/redact.ts";
3
4
  import { AuthUnavailable, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
4
5
  function unavailable(cause) {
@@ -14,7 +15,7 @@ export function betterAuthSessions(getSession, getProviderAccounts) {
14
15
  const providerAccounts = Effect.tryPromise({
15
16
  catch: (cause) => cause,
16
17
  try: () => getProviderAccounts(transport),
17
- }).pipe(Effect.catch((cause) => Predicate.hasProperty(cause, "statusCode") && cause.statusCode === 401
18
+ }).pipe(Effect.catch((cause) => Predicate.hasProperty(cause, "statusCode") && cause.statusCode === HttpStatus.fromLiteral("Unauthorized")
18
19
  ? Effect.fail(new Unauthorized({ message: "Authentication required" }))
19
20
  : unavailable(cause)));
20
21
  return Option.some({ ...session, user: { ...session.user, providerAccounts } });
@@ -1 +1 @@
1
- {"version":3,"file":"betterAuthSessions.js","sourceRoot":"","sources":["../../../src/server/adapters/betterAuthSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnD,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAQ9E,SAAS,WAAW,CAAC,KAAc;IAClC,OAAO,MAAM,CAAC,OAAO,CACpB,MAAM,CAAC,QAAQ,CAAC,gCAAgC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAChE,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,EAAE,OAAO,EAAE,2CAA2C,EAAE,CAAC,CAAC,CAC1F,CAAC;AACH,CAAC;AAMD,MAAM,UAAU,kBAAkB,CAAgC,UAAgC,EAAE,mBAAyC;IAC5I,MAAM,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAC,+BAA+B,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAwB;QACvG,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9H,IAAI,OAAO,KAAK,IAAI,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;YAC3D,OAAO,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QACD,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC;YAC1C,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;YACvB,GAAG,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC;SACzC,CAAC,CAAC,IAAI,CACN,MAAM,CAAC,KAAK,CACX,CAAC,KAAK,EAAwD,EAAE,CAC/D,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG;YACrE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;YACvE,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CACtB,CACD,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"betterAuthSessions.js","sourceRoot":"","sources":["../../../src/server/adapters/betterAuthSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnD,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAQ9E,SAAS,WAAW,CAAC,KAAc;IAClC,OAAO,MAAM,CAAC,OAAO,CACpB,MAAM,CAAC,QAAQ,CAAC,gCAAgC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAChE,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,EAAE,OAAO,EAAE,2CAA2C,EAAE,CAAC,CAAC,CAC1F,CAAC;AACH,CAAC;AAMD,MAAM,UAAU,kBAAkB,CAAgC,UAAgC,EAAE,mBAAyC;IAC5I,MAAM,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAC,+BAA+B,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAwB;QACvG,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9H,IAAI,OAAO,KAAK,IAAI,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;YAC3D,OAAO,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QACD,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC;YAC1C,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;YACvB,GAAG,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC;SACzC,CAAC,CAAC,IAAI,CACN,MAAM,CAAC,KAAK,CACX,CAAC,KAAK,EAAwD,EAAE,CAC/D,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,KAAK,CAAC,UAAU,KAAK,UAAU,CAAC,WAAW,CAAC,cAAc,CAAC;YACxG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;YACvE,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CACtB,CACD,CAAC;QACF,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,CAAC;AACnC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mountRoutes.d.ts","sourceRoot":"","sources":["../../../src/server/better-auth/mountRoutes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAyC,MAAM,aAAa,CAAC;AAChF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE5D,OAAO,EAAE,KAAK,qBAAqB,EAA2D,MAAM,uCAAuC,CAAC;AAI5I,UAAU,WAAW;IACpB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,WAAW,EAAE;YAAE,QAAQ,CAAC,YAAY,EAAE;gBAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;IAC3G,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC1D;AACD,UAAU,iBAAiB;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IAC5D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C;AAuCD,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,iBAAiB,qEAexE"}
1
+ {"version":3,"file":"mountRoutes.d.ts","sourceRoot":"","sources":["../../../src/server/better-auth/mountRoutes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAyC,MAAM,aAAa,CAAC;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE5D,OAAO,EAAE,KAAK,qBAAqB,EAA2D,MAAM,uCAAuC,CAAC;AAI5I,UAAU,WAAW;IACpB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,WAAW,EAAE;YAAE,QAAQ,CAAC,YAAY,EAAE;gBAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;IAC3G,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC1D;AACD,UAAU,iBAAiB;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IAC5D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C;AAuCD,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,iBAAiB,qEAqBxE"}
@@ -1,5 +1,6 @@
1
1
  import { Effect } from "effect";
2
2
  import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/http";
3
+ import * as HttpStatus from "effect/http/HttpStatus";
3
4
  import { redact } from "@shivaedev/errors/redact.ts";
4
5
  import { cookieSessionResponse, hasSessionCookie, sessionHeaders } from "#server/better-auth/bearerSessions.ts";
5
6
  import { clientIpHeaders } from "./clientIp.js";
@@ -46,6 +47,6 @@ export function mountRoutes(auth, options) {
46
47
  const web = yield* HttpServerRequest.toWeb(request);
47
48
  setClientIp(request, web);
48
49
  return HttpServerResponse.fromWeb(yield* Effect.tryPromise(() => authResponse(auth, web, options)).pipe(Effect.tapError((error) => Effect.logError("Authentication provider failed", redact(error.cause)))));
49
- }).pipe(Effect.catch(() => Effect.succeed(HttpServerResponse.text("Authentication is temporarily unavailable", { status: 503 }))))));
50
+ }).pipe(Effect.catch(() => Effect.succeed(HttpServerResponse.text("Authentication is temporarily unavailable", { status: HttpStatus.fromLiteral("ServiceUnavailable") }))))));
50
51
  }
51
52
  //# sourceMappingURL=mountRoutes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mountRoutes.js","sourceRoot":"","sources":["../../../src/server/better-auth/mountRoutes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mountRoutes.js","sourceRoot":"","sources":["../../../src/server/better-auth/mountRoutes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ export declare const sweepExpiredSessions: Effect.Effect<number, Schema.SchemaError | import("effect/sql/SqlError").SqlError, SqlClient.SqlClient>;
4
+ //# sourceMappingURL=sweepExpiredSessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sweepExpiredSessions.d.ts","sourceRoot":"","sources":["../../../src/server/better-auth/sweepExpiredSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIvC,eAAO,MAAM,oBAAoB,yGAOwB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ const SweepResult = Schema.Tuple([Schema.Struct({ removed: Schema.NumberFromString })]);
4
+ export const sweepExpiredSessions = Effect.gen(function* () {
5
+ const sql = yield* SqlClient.SqlClient;
6
+ const rows = yield* sql `with expired as (
7
+ delete from "session" where "expiresAt" <= now() returning 1
8
+ ) select count(*)::text as removed from expired`;
9
+ const [result] = yield* Schema.decodeUnknownEffect(SweepResult)(rows);
10
+ return result.removed;
11
+ }).pipe(Effect.withSpan("Identity.sweepExpiredSessions"));
12
+ //# sourceMappingURL=sweepExpiredSessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sweepExpiredSessions.js","sourceRoot":"","sources":["../../../src/server/better-auth/sweepExpiredSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC;AAExF,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IACvD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC;IACvC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAA;;iDAEyB,CAAC;IACjD,MAAM,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC;IACtE,OAAO,MAAM,CAAC,OAAO,CAAC;AACvB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,+BAA+B,CAAC,CAAC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { Effect } from "effect";
2
2
  import type { Pool } from "pg";
3
3
  export declare function authTestDatabase(pool: Pool): {
4
- expireSessions: Effect.Effect<void, import("effect/Cause").UnknownError, never>;
4
+ expireSessions: (userId?: string) => Effect.Effect<void, import("effect/Cause").UnknownError, never>;
5
5
  omitImageColumn: Effect.Effect<void, import("effect/Cause").UnknownError, never>;
6
6
  sessionIpAddresses: Effect.Effect<{
7
7
  ipAddress: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"testDatabase.d.ts","sourceRoot":"","sources":["../../../src/server/better-auth/testDatabase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI;IAEzC,cAAc;IAGd,eAAe;IAGf,kBAAkB;mBAC4B,MAAM,GAAG,IAAI;;IAG3D,QAAQ;eACkC,MAAM;YAAM,MAAM;gBAAU,MAAM;;IAK5E,KAAK;eACqC,MAAM;YAAM,MAAM;;EAI7D"}
1
+ {"version":3,"file":"testDatabase.d.ts","sourceRoot":"","sources":["../../../src/server/better-auth/testDatabase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI;IAEzC,cAAc,YAAY,MAAM;IAOhC,eAAe;IAGf,kBAAkB;mBAC4B,MAAM,GAAG,IAAI;;IAG3D,QAAQ;eACkC,MAAM;YAAM,MAAM;gBAAU,MAAM;;IAK5E,KAAK;eACqC,MAAM;YAAM,MAAM;;EAI7D"}
@@ -1,8 +1,8 @@
1
1
  import { Effect } from "effect";
2
2
  export function authTestDatabase(pool) {
3
3
  return {
4
- expireSessions: Effect.tryPromise(async () => {
5
- await pool.query('update "session" set "expiresAt" = now() - interval \'1 second\'');
4
+ expireSessions: (userId) => Effect.tryPromise(async () => {
5
+ await pool.query(`update "session" set "expiresAt" = now() - interval '1 second'${userId === undefined ? "" : ' where "userId" = $1'}`, userId === undefined ? [] : [userId]);
6
6
  }),
7
7
  omitImageColumn: Effect.tryPromise(async () => {
8
8
  await pool.query('alter table "user" drop column image');
@@ -1 +1 @@
1
- {"version":3,"file":"testDatabase.js","sourceRoot":"","sources":["../../../src/server/better-auth/testDatabase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,MAAM,UAAU,gBAAgB,CAAC,IAAU;IAC1C,OAAO;QACN,cAAc,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YAC5C,MAAM,IAAI,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;QACtF,CAAC,CAAC;QACF,eAAe,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YAC7C,MAAM,IAAI,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC,CAAC;QACF,kBAAkB,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YAChD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAA+B,4DAA4D,CAAC,CAAC;YAC5H,OAAO,MAAM,CAAC,IAAI,CAAC;QACpB,CAAC,CAAC;QACF,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAC9B,6GAA6G,CAC7G,CAAC;YACF,OAAO,MAAM,CAAC,IAAI,CAAC;QACpB,CAAC,CAAC;QACF,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YACnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAgC,6CAA6C,CAAC,CAAC;YAC9G,OAAO,MAAM,CAAC,IAAI,CAAC;QACpB,CAAC,CAAC;KACF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"testDatabase.js","sourceRoot":"","sources":["../../../src/server/better-auth/testDatabase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,MAAM,UAAU,gBAAgB,CAAC,IAAU;IAC1C,OAAO;QACN,cAAc,EAAE,CAAC,MAAe,EAAE,EAAE,CACnC,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YAC5B,MAAM,IAAI,CAAC,KAAK,CACf,iEAAiE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,sBAAsB,EAAE,EACrH,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CACpC,CAAC;QACH,CAAC,CAAC;QACH,eAAe,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YAC7C,MAAM,IAAI,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC,CAAC;QACF,kBAAkB,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YAChD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAA+B,4DAA4D,CAAC,CAAC;YAC5H,OAAO,MAAM,CAAC,IAAI,CAAC;QACpB,CAAC,CAAC;QACF,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAC9B,6GAA6G,CAC7G,CAAC;YACF,OAAO,MAAM,CAAC,IAAI,CAAC;QACpB,CAAC,CAAC;QACF,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YACnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAgC,6CAA6C,CAAC,CAAC;YAC9G,OAAO,MAAM,CAAC,IAAI,CAAC;QACpB,CAAC,CAAC;KACF,CAAC;AACH,CAAC"}
@@ -1,5 +1,4 @@
1
1
  import { Effect } from "effect";
2
2
  import type { Rpc } from "effect/rpc";
3
- export declare function sessionCommandChanges<A, E, R>(effect: Effect.Effect<A, E, R>, rpc: Rpc.AnyWithProps, payload: unknown): Effect.Effect<A, E, R>;
4
3
  export declare function commandChanges<A, E, R>(effect: Effect.Effect<A, E, R>, rpc: Rpc.AnyWithProps, payload: unknown): Effect.Effect<A, E, R>;
5
4
  //# sourceMappingURL=commandChanges.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commandChanges.d.ts","sourceRoot":"","sources":["../../src/server/commandChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,MAAM,EAAU,MAAM,QAAQ,CAAC;AAEjD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAOtC,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,0BAErH;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,0BAsC9G"}
1
+ {"version":3,"file":"commandChanges.d.ts","sourceRoot":"","sources":["../../src/server/commandChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,MAAM,EAAU,MAAM,QAAQ,CAAC;AAEjD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAQtC,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,0BAuC9G"}
@@ -1,19 +1,17 @@
1
1
  import { Context, Effect, Option } from "effect";
2
2
  import * as Reactivity from "effect/reactivity/Reactivity";
3
3
  import { SqlClient } from "effect/sql";
4
- import { invalidationKeys } from "@shivaedev/contract/keys.ts";
5
- import { CommandInvalidation, KeyScope } from "@shivaedev/contract/serverMetadata.ts";
4
+ import { invalidationKeys } from "@shivaedev/changes/keys.ts";
5
+ import { CurrentViewer } from "@shivaedev/contract/readPolicy.ts";
6
+ import { CommandInvalidation } from "@shivaedev/contract/serverMetadata.ts";
6
7
  import { ChangeObserver, invalidateOnCommit, transact } from "@shivaedev/sql/transact.ts";
7
8
  import { sessionKeyContext } from "#server/sessionKeys.ts";
8
- export function sessionCommandChanges(effect, rpc, payload) {
9
- return Option.isSome(Context.getOption(rpc.annotations, KeyScope)) ? commandChanges(effect, rpc, payload) : effect;
10
- }
11
9
  export function commandChanges(effect, rpc, payload) {
12
10
  const invalidates = Context.getOption(rpc.annotations, CommandInvalidation);
13
11
  if (Option.isNone(invalidates)) {
14
12
  return effect;
15
13
  }
16
- const declared = invalidates.value;
14
+ const declared = invalidates.value.invalidates;
17
15
  return Effect.gen(function* () {
18
16
  const context = yield* sessionKeyContext(rpc);
19
17
  const sql = yield* Effect.serviceOption(SqlClient.SqlClient);
@@ -31,7 +29,8 @@ export function commandChanges(effect, rpc, payload) {
31
29
  }
32
30
  return observer(event);
33
31
  }));
34
- const keys = invalidationKeys(declared(payload, result), context).filter((key) => !published.has(key));
32
+ const viewer = yield* CurrentViewer;
33
+ const keys = invalidationKeys(declared(payload, result, viewer), context).filter((key) => !published.has(key));
35
34
  if (keys.length > 0) {
36
35
  const announce = Option.isNone(sql)
37
36
  ? reactivity.value.invalidate(keys)
@@ -1 +1 @@
1
- {"version":3,"file":"commandChanges.js","sourceRoot":"","sources":["../../src/server/commandChanges.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commandChanges.js","sourceRoot":"","sources":["../../src/server/commandChanges.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/server/local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAoB,MAAM,aAAa,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAsB9C,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,GAAG,OAAO,CAWhF;AACD,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAChC,OAAO,EAAE,CAAC,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,KAAK,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC,aAEpG,iBAAiB,CAAC,iBAAiB,gEAIpD;AACD,wBAAgB,gBAAgB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAGpF;AACD,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAElE;AAkBD,wBAAgB,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,aAAa,GAAE,SAAS,MAAM,EAAO,aAEzE,iBAAiB,CAAC,iBAAiB,KAAG,OAAO,CAK9D;AACD,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EACjC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC,EAClE,YAAY,CAAC,EAAE,MAAM,EACrB,aAAa,GAAE,SAAS,MAAM,EAAO,wIAWrC"}
1
+ {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/server/local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAoB,MAAM,aAAa,CAAC;AAEtF,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAsB9C,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,GAAG,OAAO,CAWhF;AACD,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAChC,OAAO,EAAE,CAAC,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,KAAK,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC,aAEpG,iBAAiB,CAAC,iBAAiB,gEAIpD;AACD,wBAAgB,gBAAgB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAGpF;AACD,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAElE;AAkBD,wBAAgB,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,aAAa,GAAE,SAAS,MAAM,EAAO,aAEzE,iBAAiB,CAAC,iBAAiB,KAAG,OAAO,CAK9D;AACD,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EACjC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC,EAClE,YAAY,CAAC,EAAE,MAAM,EACrB,aAAa,GAAE,SAAS,MAAM,EAAO,wIAWrC"}
@@ -1,5 +1,6 @@
1
1
  import { Effect, Option } from "effect";
2
2
  import { HttpServerRequest, HttpServerResponse, HttpTraceContext } from "effect/http";
3
+ import * as HttpStatus from "effect/http/HttpStatus";
3
4
  import { RpcSerialization } from "effect/rpc";
4
5
  import { proxyAddresses, proxyMatches } from "./trustedProxy.js";
5
6
  import { trustedProxyRanges as normalizedRanges } from "./trustedProxyRanges.js";
@@ -37,7 +38,7 @@ export function sameOrigin(request) {
37
38
  export function loopbackOnly(handler) {
38
39
  return (request) => loopbackHost(request.headers.host) && Option.match(request.remoteAddress, { onNone: () => true, onSome: loopbackAddress })
39
40
  ? handler(request)
40
- : Effect.succeed(HttpServerResponse.text("Only loopback hosts are served", { status: 403 }));
41
+ : Effect.succeed(HttpServerResponse.text("Only loopback hosts are served", { status: HttpStatus.fromLiteral("Forbidden") }));
41
42
  }
42
43
  export function trustedProxyPeer(trustedProxy) {
43
44
  const addresses = trustedProxy === undefined ? undefined : proxyAddresses(trustedProxy);
@@ -79,7 +80,7 @@ export function localRpcGuard(effect, trustedProxy, nativeOrigins = []) {
79
80
  const contentType = request.headers["content-type"]?.split(";")[0]?.trim().toLowerCase();
80
81
  return allowed(request) && contentType === serialization.contentType
81
82
  ? yield* continueHttpTrace(effect, request)
82
- : HttpServerResponse.text("Local same-origin requests only", { status: 403 });
83
+ : HttpServerResponse.text("Local same-origin requests only", { status: HttpStatus.fromLiteral("Forbidden") });
83
84
  });
84
85
  }
85
86
  const continueHttpTrace = Effect.fnUntraced(function* (effect, request) {
@@ -1 +1 @@
1
- {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/server/local.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/server/local.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/server/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAU,MAAM,QAAQ,CAAC;AAC/C,OAAO,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAiB,KAAK,oBAAoB,EAAqB,MAAM,gBAAgB,CAAC;AAG7F,OAAO,EAAkB,KAAK,aAAa,EAAE,KAAK,gBAAgB,EAAmB,MAAM,cAAc,CAAC;AAE1G,wBAAgB,eAAe,CAAC,WAAW,EAAE,QAAQ,SAAS,gBAAgB,EAC7E,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,EAC5E,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,0CAmB/B;AAQD,wBAAgB,eAAe,CAAC,QAAQ,SAAS,gBAAgB,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,UAAU,IACjH,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,KAAK,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC,eACxH,iBAAiB,CAAC,iBAAiB,KAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC,CAAC,CAQ5I"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/server/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAU,MAAM,QAAQ,CAAC;AAC/C,OAAO,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAIlE,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAiB,KAAK,oBAAoB,EAAqB,MAAM,gBAAgB,CAAC;AAG7F,OAAO,EAAkB,KAAK,aAAa,EAAE,KAAK,gBAAgB,EAAmB,MAAM,cAAc,CAAC;AAE1G,wBAAgB,eAAe,CAAC,WAAW,EAAE,QAAQ,SAAS,gBAAgB,EAC7E,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,EAC5E,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,0CAoB/B;AAYD,wBAAgB,eAAe,CAAC,QAAQ,SAAS,gBAAgB,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,UAAU,IACjH,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,KAAK,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC,eACxH,iBAAiB,CAAC,iBAAiB,KAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC,CAAC,CAQ5I"}
@@ -1,9 +1,11 @@
1
1
  import { Effect, Layer, Option } from "effect";
2
2
  import { HttpServerResponse } from "effect/http";
3
+ import * as HttpStatus from "effect/http/HttpStatus";
4
+ import { authorizeReads } from "@shivaedev/contract/readPolicy.ts";
3
5
  import { Forbidden } from "@shivaedev/errors/taxonomy.ts";
4
6
  import { Identity } from "#identity.ts";
5
7
  import { hasPermission, requirePermission } from "#permission.ts";
6
- import { sessionCommandChanges } from "#server/commandChanges.ts";
8
+ import { commandChanges } from "#server/commandChanges.ts";
7
9
  import { revalidateStream } from "./revalidateStream.js";
8
10
  import { resolveSession, withSessionUser } from "./session.js";
9
11
  export function permissionLayer(middleware, policy) {
@@ -12,14 +14,18 @@ export function permissionLayer(middleware, policy) {
12
14
  const lookup = Effect.tap(resolveSession(policy, headers, rpc._tag), (session) => Option.isSome(session) && !hasPermission(session.value.user, permission)
13
15
  ? Effect.fail(new Forbidden({ message: `Permission required: ${permission.name} (${permission.strength})` }))
14
16
  : Effect.void);
15
- return sessionCommandChanges(effect, rpc, payload).pipe((invocation) => Effect.flatMap(Identity, ({ id }) => invocation.pipe(revalidateStream(policy, rpc, id, lookup))), (invocation) => Effect.andThen(requirePermission(permission), invocation), withSessionUser(policy, headers, rpc._tag));
17
+ return Effect.flatMap(Identity, (viewer) => authorizeReads(commandChanges(effect, rpc, payload), { payload, rpc }, Option.some(viewer))).pipe((invocation) => Effect.flatMap(Identity, ({ id }) => invocation.pipe(revalidateStream(policy, rpc, id, lookup))), (invocation) => Effect.andThen(requirePermission(permission), invocation), withSessionUser(policy, headers, rpc._tag));
16
18
  };
17
19
  return Layer.succeed(middleware, guard);
18
20
  }
19
21
  function rejection(error) {
20
22
  return HttpServerResponse.empty({
21
23
  headers: { "cache-control": "private, no-store" },
22
- status: { AuthUnavailable: 503, Forbidden: 403, Unauthorized: 401 }[error._tag],
24
+ status: {
25
+ AuthUnavailable: HttpStatus.fromLiteral("ServiceUnavailable"),
26
+ Forbidden: HttpStatus.fromLiteral("Forbidden"),
27
+ Unauthorized: HttpStatus.fromLiteral("Unauthorized"),
28
+ }[error._tag],
23
29
  });
24
30
  }
25
31
  export function permissionRoute(policy, permission) {
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/server/permissions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/server/permissions.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/server/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/server/session.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  import { Duration, Effect, Exit, Layer, Option } from "effect";
2
+ import { authorizeReads } from "@shivaedev/contract/readPolicy.ts";
2
3
  import { Forbidden, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
3
4
  import { Identity, OptionalIdentity, SessionUser, SessionUserWithProviderAccounts, } from "#identity.ts";
4
5
  import { Authenticated, AuthenticatedUser, AuthenticatedUserWithProviderAccounts, MaybeAuthenticated } from "#middleware.ts";
5
- import { sessionCommandChanges } from "#server/commandChanges.ts";
6
+ import { commandChanges } from "#server/commandChanges.ts";
6
7
  import { originRequest } from "./origin.js";
7
8
  import { resolveRole } from "./resolveRole.js";
8
9
  import { revalidateStream } from "./revalidateStream.js";
@@ -30,17 +31,17 @@ export function authenticatedLayer(policy) {
30
31
  return yield* new Unauthorized({ message: "Authentication required" });
31
32
  }
32
33
  const id = yield* identified(session.value.user.id);
33
- return yield* sessionCommandChanges(effect, rpc, payload).pipe(revalidateStream(policy, rpc, id, resolveSession(policy, headers, rpc._tag)), Effect.provideService(Identity, { id }), Effect.annotateLogs({ userId: id }));
34
+ return yield* authorizeReads(commandChanges(effect, rpc, payload), { payload, rpc }, Option.some({ id })).pipe(revalidateStream(policy, rpc, id, resolveSession(policy, headers, rpc._tag)), Effect.provideService(Identity, { id }), Effect.annotateLogs({ userId: id }));
34
35
  }));
35
36
  }
36
37
  export function maybeAuthenticatedLayer(policy) {
37
- return Layer.succeed(MaybeAuthenticated, (effect, { headers, rpc }) => Effect.gen(function* () {
38
+ return Layer.succeed(MaybeAuthenticated, (effect, { headers, rpc, payload }) => Effect.gen(function* () {
38
39
  const session = yield* resolveSession(policy, headers, rpc._tag);
39
40
  if (Option.isNone(session)) {
40
- return yield* Effect.provideService(effect, OptionalIdentity, Option.none());
41
+ return yield* Effect.provideService(authorizeReads(effect, { payload, rpc }, Option.none()), OptionalIdentity, Option.none());
41
42
  }
42
43
  const id = yield* identified(session.value.user.id);
43
- return yield* effect.pipe(revalidateStream(policy, rpc, id, resolveSession(policy, headers, rpc._tag)), Effect.provideService(OptionalIdentity, Option.some({ id })), Effect.annotateLogs({ userId: id }));
44
+ return yield* authorizeReads(effect, { payload, rpc }, Option.some({ id })).pipe(revalidateStream(policy, rpc, id, resolveSession(policy, headers, rpc._tag)), Effect.provideService(OptionalIdentity, Option.some({ id })), Effect.annotateLogs({ userId: id }));
44
45
  }));
45
46
  }
46
47
  export function withSessionUser(policy, headers, operation) {
@@ -55,7 +56,7 @@ export function withSessionUser(policy, headers, operation) {
55
56
  });
56
57
  }
57
58
  export function authenticatedUserLayer(policy) {
58
- return Layer.succeed(AuthenticatedUser, (effect, { headers, rpc, payload }) => sessionCommandChanges(effect, rpc, payload).pipe((invocation) => Effect.flatMap(Identity, ({ id }) => invocation.pipe(revalidateStream(policy, rpc, id, resolveSession(policy, headers, rpc._tag)))), withSessionUser(policy, headers, rpc._tag)));
59
+ return Layer.succeed(AuthenticatedUser, (effect, { headers, rpc, payload }) => Effect.flatMap(Identity, (viewer) => authorizeReads(commandChanges(effect, rpc, payload), { payload, rpc }, Option.some(viewer))).pipe((invocation) => Effect.flatMap(Identity, ({ id }) => invocation.pipe(revalidateStream(policy, rpc, id, resolveSession(policy, headers, rpc._tag)))), withSessionUser(policy, headers, rpc._tag)));
59
60
  }
60
61
  export function authenticatedUserWithProviderAccountsLayer(policy) {
61
62
  return Layer.succeed(AuthenticatedUserWithProviderAccounts, (effect, { headers, rpc, payload }) => Effect.gen(function* () {
@@ -67,7 +68,7 @@ export function authenticatedUserWithProviderAccountsLayer(policy) {
67
68
  const accounts = yield* Effect.cachedWithTTL(Effect.map(providerAccounts, (values) => values.map(({ accountId, providerId }) => ({ accountId, providerId }))), (exit) => (Exit.isSuccess(exit) ? Duration.infinity : Duration.zero));
68
69
  const user = sessionProfile(session.value.user);
69
70
  yield* identified(id);
70
- return yield* sessionCommandChanges(effect, rpc, payload).pipe(revalidateStream(policy, rpc, id, resolveSession(policy, headers, rpc._tag)), Effect.provideService(Identity, { id }), Effect.provideService(SessionUser, user), Effect.provideService(SessionUserWithProviderAccounts, { ...user, providerAccounts: accounts }), Effect.annotateLogs({ userId: id }));
71
+ return yield* authorizeReads(commandChanges(effect, rpc, payload), { payload, rpc }, Option.some({ id })).pipe(revalidateStream(policy, rpc, id, resolveSession(policy, headers, rpc._tag)), Effect.provideService(Identity, { id }), Effect.provideService(SessionUser, user), Effect.provideService(SessionUserWithProviderAccounts, { ...user, providerAccounts: accounts }), Effect.annotateLogs({ userId: id }));
71
72
  }));
72
73
  }
73
74
  //# sourceMappingURL=session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/server/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/server/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAI/D,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAwB,SAAS,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC9F,OAAO,EACN,QAAQ,EACR,gBAAgB,EAChB,WAAW,EAEX,+BAA+B,GAE/B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,qCAAqC,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC7H,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAqB,aAAa,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAezD,MAAM,CAAC,MAAM,cAAc,GAK1B,MAAM,CAAC,EAAE,CAAC,4BAA4B,CAAC,CAAC,QAAQ,CAAC,EAChD,MAA+B,EAC/B,OAAwB,EACxB,GAAW;IAEX,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;QACnD,OAAO,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1D,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACzF,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;AACtF,CAAC,CAAC,CAAC;AACJ,SAAS,UAAU,CAAC,EAAU;IAC7B,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;AACtF,CAAC;AACD,MAAM,UAAU,kBAAkB,CAAgC,MAA+B;IAChG,OAAO,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CACzE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAC7G,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,EAC5E,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,EACvC,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CACnC,CAAC;IACH,CAAC,CAAC,CACF,CAAC;AACH,CAAC;AACD,MAAM,UAAU,uBAAuB,CAAgC,MAA+B;IACrG,OAAO,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAC9E,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,gBAAgB,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/H,CAAC;QACD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAC/E,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,EAC5E,MAAM,CAAC,cAAc,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAC5D,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CACnC,CAAC;IACH,CAAC,CAAC,CACF,CAAC;AACH,CAAC;AAID,MAAM,UAAU,eAAe,CAAoC,MAA+B,EAAE,OAAwB,EAAE,SAAiB;IAC9I,OAAO,CAAU,MAA8B,EAAE,EAAE,CAClD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QAClE,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACxB,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,EACvC,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC,EACxC,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CACnC,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AACD,MAAM,UAAU,sBAAsB,CAAoC,MAA+B;IACxG,OAAO,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAC7E,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CACrI,CAAC,UAAU,EAAE,EAAE,CACd,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EACpI,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAC1C,CACD,CAAC;AACH,CAAC;AAKD,MAAM,UAAU,0CAA0C,CACzD,MAA+B;IAE/B,OAAO,KAAK,CAAC,OAAO,CAAC,qCAAqC,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CACjG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,EAAE,EAAE,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;QACpD,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAC3C,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAChH,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CACpE,CAAC;QACF,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChD,KAAK,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACtB,OAAO,KAAK,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAC7G,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,EAC5E,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,EACvC,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC,EACxC,MAAM,CAAC,cAAc,CAAC,+BAA+B,EAAE,EAAE,GAAG,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC,EAC/F,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CACnC,CAAC;IACH,CAAC,CAAC,CACF,CAAC;AACH,CAAC"}
@@ -1,10 +1,14 @@
1
1
  import { Effect } from "effect";
2
2
  import type { Rpc } from "effect/rpc";
3
- import type { KeyContext } from "@shivaedev/contract/keys.ts";
3
+ import type { KeyContext } from "@shivaedev/changes/keys.ts";
4
4
  import { type QueryReference } from "@shivaedev/contract/serverMetadata.ts";
5
5
  export declare function sessionKeyContext(rpc: Pick<Rpc.AnyWithProps, "annotations">): Effect.Effect<KeyContext | undefined>;
6
- export declare function resolveChanges(rpc: Pick<Rpc.AnyWithProps, "annotations">, references: readonly QueryReference[]): Effect.Effect<{
6
+ export declare const resolveChanges: (rpc: Pick<Rpc.AnyWithProps, "annotations">, references: readonly QueryReference[]) => Effect.Effect<{
7
7
  context: KeyContext | undefined;
8
- keys: readonly import("@shivaedev/contract/keys.ts").Key[];
9
- }, never, never>;
8
+ subscription: {
9
+ authorized: Effect.Effect<boolean, never, never>;
10
+ keys: import("@shivaedev/changes/keys.ts").Key[];
11
+ scopes: (readonly import("@shivaedev/changes/keys.ts").Key[])[];
12
+ };
13
+ }, import("@shivaedev/contract/readPolicyErrors.ts").MissingReadPolicy | import("@shivaedev/contract/readPolicyErrors.ts").QueryReadDenied, never>;
10
14
  //# sourceMappingURL=sessionKeys.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sessionKeys.d.ts","sourceRoot":"","sources":["../../src/server/sessionKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,MAAM,EAAU,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAGpG,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC,CAWnH;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,EAAE,UAAU,EAAE,SAAS,cAAc,EAAE;;;iBAK/G"}
1
+ {"version":3,"file":"sessionKeys.d.ts","sourceRoot":"","sources":["../../src/server/sessionKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,MAAM,EAAU,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAG7D,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAGtG,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC,CAWnH;AAED,eAAO,MAAM,cAAc;;;;;;;kJAOzB,CAAC"}
@@ -1,5 +1,7 @@
1
1
  import { Context, Effect, Option } from "effect";
2
- import { ChangesReads, KeyScope } from "@shivaedev/contract/serverMetadata.ts";
2
+ import { querySubscription } from "@shivaedev/contract/querySubscription.ts";
3
+ import { CurrentViewer } from "@shivaedev/contract/readPolicy.ts";
4
+ import { ChangesQueries, KeyScope } from "@shivaedev/contract/serverMetadata.ts";
3
5
  import { Identity } from "#identity.ts";
4
6
  export function sessionKeyContext(rpc) {
5
7
  if (Option.isNone(Context.getOption(rpc.annotations, KeyScope))) {
@@ -13,10 +15,12 @@ export function sessionKeyContext(rpc) {
13
15
  return { scope: identity.value.id };
14
16
  });
15
17
  }
16
- export function resolveChanges(rpc, references) {
17
- return Effect.map(sessionKeyContext(rpc), (context) => ({
18
- context,
19
- keys: Context.getUnsafe(rpc.annotations, ChangesReads)(references),
20
- }));
21
- }
18
+ export const resolveChanges = Effect.fnUntraced(function* (rpc, references) {
19
+ const identity = yield* Effect.serviceOption(Identity);
20
+ const current = yield* CurrentViewer;
21
+ const viewer = Option.orElse(identity, () => current);
22
+ const queries = yield* Context.getUnsafe(rpc.annotations, ChangesQueries).resolve(references);
23
+ const subscription = yield* querySubscription(queries, viewer);
24
+ return { context: yield* sessionKeyContext(rpc), subscription };
25
+ });
22
26
  //# sourceMappingURL=sessionKeys.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sessionKeys.js","sourceRoot":"","sources":["../../src/server/sessionKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGjD,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAuB,MAAM,uCAAuC,CAAC;AACpG,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,MAAM,UAAU,iBAAiB,CAAC,GAA0C;IAC3E,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;QACjE,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC1B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC,CAAC;QACpG,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;IACrC,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAA0C,EAAE,UAAqC;IAC/G,OAAO,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACvD,OAAO;QACP,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,UAAU,CAAC;KAClE,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"sessionKeys.js","sourceRoot":"","sources":["../../src/server/sessionKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAuB,MAAM,uCAAuC,CAAC;AACtG,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,MAAM,UAAU,iBAAiB,CAAC,GAA0C;IAC3E,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;QACjE,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC1B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC,CAAC;QACpG,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;IACrC,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,GAA0C,EAAE,UAAqC;IAC3I,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9F,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/D,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC;AACjE,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shivaedev/identity",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Request identity, sessions, transport trust and permission enforcement for Effect RPC servers",
5
5
  "keywords": [
6
6
  "effect"
@@ -45,26 +45,27 @@
45
45
  ],
46
46
  "dependencies": {
47
47
  "@shivaedev/access": "0.1.1",
48
- "@shivaedev/contract": "0.18.0",
48
+ "@shivaedev/changes": "0.5.0",
49
+ "@shivaedev/contract": "0.19.0",
49
50
  "@shivaedev/errors": "0.1.0",
50
- "@shivaedev/sql": "0.23.0"
51
+ "@shivaedev/sql": "0.24.0"
51
52
  },
52
53
  "devDependencies": {
53
54
  "@effect/platform-node": "4.0.5",
54
55
  "@effect/sql-pg": "4.0.5",
55
- "@shivaedev/quality": "0.42.0",
56
- "@shivaedev/test-sql": "0.10.1",
57
- "@shivaedev/test-story": "0.21.1",
56
+ "@shivaedev/quality": "0.43.0",
57
+ "@shivaedev/test-sql": "0.10.2",
58
+ "@shivaedev/test-story": "0.22.0",
58
59
  "@types/node": "24.19.2",
59
60
  "@types/pg": "8.20.0",
60
- "better-auth": "1.7.11",
61
+ "better-auth": "1.7.12",
61
62
  "effect": "4.0.5",
62
63
  "pg": "8.23.0",
63
64
  "typescript": "7.0.2",
64
65
  "vitest": "5.0.5"
65
66
  },
66
67
  "peerDependencies": {
67
- "better-auth": "1.7.11",
68
+ "better-auth": "1.7.12",
68
69
  "effect": "4.0.5",
69
70
  "pg": "8.23.0"
70
71
  },
package/src/middleware.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Schema } from "effect";
2
2
  import { RpcMiddleware } from "effect/rpc";
3
+ import { MissingReadPolicy, QueryReadDenied } from "@shivaedev/contract/readPolicyErrors.ts";
3
4
  import { AuthUnavailable, Forbidden, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
4
5
  import type { Identity, OptionalIdentity, RequestId, SessionUser, SessionUserWithProviderAccounts } from "./identity.ts";
5
6
  export class RequestTracing extends RpcMiddleware.Service<
@@ -14,25 +15,27 @@ export class Authenticated extends RpcMiddleware.Service<
14
15
  provides: Identity;
15
16
  }
16
17
  >()("@shivaedev/identity/Authenticated", {
17
- error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]),
18
+ error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden, MissingReadPolicy, QueryReadDenied]),
18
19
  }) {}
19
20
  export class MaybeAuthenticated extends RpcMiddleware.Service<
20
21
  MaybeAuthenticated,
21
22
  {
22
23
  provides: OptionalIdentity;
23
24
  }
24
- >()("@shivaedev/identity/MaybeAuthenticated", { error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]) }) {}
25
+ >()("@shivaedev/identity/MaybeAuthenticated", {
26
+ error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden, MissingReadPolicy, QueryReadDenied]),
27
+ }) {}
25
28
  export class AuthenticatedUser extends RpcMiddleware.Service<
26
29
  AuthenticatedUser,
27
30
  {
28
31
  provides: Identity | SessionUser;
29
32
  }
30
33
  >()("@shivaedev/identity/AuthenticatedUser", {
31
- error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]),
34
+ error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden, MissingReadPolicy, QueryReadDenied]),
32
35
  }) {}
33
36
  export class AuthenticatedUserWithProviderAccounts extends RpcMiddleware.Service<
34
37
  AuthenticatedUserWithProviderAccounts,
35
38
  { provides: Identity | SessionUser | SessionUserWithProviderAccounts }
36
39
  >()("@shivaedev/identity/AuthenticatedUserWithProviderAccounts", {
37
- error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]),
40
+ error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden, MissingReadPolicy, QueryReadDenied]),
38
41
  }) {}
package/src/permission.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { Effect, Schema } from "effect";
2
2
  import { RpcMiddleware } from "effect/rpc";
3
3
  import type { Permission } from "@shivaedev/access/permission.ts";
4
+ import { MissingReadPolicy, QueryReadDenied } from "@shivaedev/contract/readPolicyErrors.ts";
4
5
  import { AuthUnavailable, Forbidden, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
5
6
  import { type Identity, SessionUser, type SessionUserValue } from "./identity.ts";
6
7
 
7
- const Failures = Schema.Union([Unauthorized, AuthUnavailable, Forbidden]);
8
+ const Failures = Schema.Union([Unauthorized, AuthUnavailable, Forbidden, MissingReadPolicy, QueryReadDenied]);
8
9
 
9
10
  export function permissionMiddleware<TSelf>() {
10
11
  return <const TName extends string>(name: TName, permission: Permission) =>
@@ -1,5 +1,6 @@
1
1
  import { Effect, Option, Predicate } from "effect";
2
2
  import type { Headers } from "effect/http";
3
+ import * as HttpStatus from "effect/http/HttpStatus";
3
4
  import { redact } from "@shivaedev/errors/redact.ts";
4
5
  import { AuthUnavailable, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
5
6
  import type { ProviderAccountValue } from "#identity.ts";
@@ -33,7 +34,7 @@ export function betterAuthSessions<TSession extends SessionShape>(getSession: Ge
33
34
  }).pipe(
34
35
  Effect.catch(
35
36
  (cause): Effect.Effect<never, AuthUnavailable | Unauthorized> =>
36
- Predicate.hasProperty(cause, "statusCode") && cause.statusCode === 401
37
+ Predicate.hasProperty(cause, "statusCode") && cause.statusCode === HttpStatus.fromLiteral("Unauthorized")
37
38
  ? Effect.fail(new Unauthorized({ message: "Authentication required" }))
38
39
  : unavailable(cause),
39
40
  ),
@@ -1,5 +1,6 @@
1
1
  import { Effect } from "effect";
2
2
  import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/http";
3
+ import * as HttpStatus from "effect/http/HttpStatus";
3
4
  import type { RoleSet } from "@shivaedev/access/roleSet.ts";
4
5
  import { redact } from "@shivaedev/errors/redact.ts";
5
6
  import { type BearerSessionsOptions, cookieSessionResponse, hasSessionCookie, sessionHeaders } from "#server/better-auth/bearerSessions.ts";
@@ -67,7 +68,13 @@ export function mountRoutes(auth: MountedAuth, options: MountRouteOptions) {
67
68
  Effect.tapError((error) => Effect.logError("Authentication provider failed", redact(error.cause))),
68
69
  ),
69
70
  );
70
- }).pipe(Effect.catch(() => Effect.succeed(HttpServerResponse.text("Authentication is temporarily unavailable", { status: 503 })))),
71
+ }).pipe(
72
+ Effect.catch(() =>
73
+ Effect.succeed(
74
+ HttpServerResponse.text("Authentication is temporarily unavailable", { status: HttpStatus.fromLiteral("ServiceUnavailable") }),
75
+ ),
76
+ ),
77
+ ),
71
78
  ),
72
79
  );
73
80
  }
@@ -0,0 +1,13 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+
4
+ const SweepResult = Schema.Tuple([Schema.Struct({ removed: Schema.NumberFromString })]);
5
+
6
+ export const sweepExpiredSessions = Effect.gen(function* () {
7
+ const sql = yield* SqlClient.SqlClient;
8
+ const rows = yield* sql`with expired as (
9
+ delete from "session" where "expiresAt" <= now() returning 1
10
+ ) select count(*)::text as removed from expired`;
11
+ const [result] = yield* Schema.decodeUnknownEffect(SweepResult)(rows);
12
+ return result.removed;
13
+ }).pipe(Effect.withSpan("Identity.sweepExpiredSessions"));
@@ -3,9 +3,13 @@ import type { Pool } from "pg";
3
3
 
4
4
  export function authTestDatabase(pool: Pool) {
5
5
  return {
6
- expireSessions: Effect.tryPromise(async () => {
7
- await pool.query('update "session" set "expiresAt" = now() - interval \'1 second\'');
8
- }),
6
+ expireSessions: (userId?: string) =>
7
+ Effect.tryPromise(async () => {
8
+ await pool.query(
9
+ `update "session" set "expiresAt" = now() - interval '1 second'${userId === undefined ? "" : ' where "userId" = $1'}`,
10
+ userId === undefined ? [] : [userId],
11
+ );
12
+ }),
9
13
  omitImageColumn: Effect.tryPromise(async () => {
10
14
  await pool.query('alter table "user" drop column image');
11
15
  }),
@@ -2,21 +2,18 @@ import { Context, Effect, Option } from "effect";
2
2
  import * as Reactivity from "effect/reactivity/Reactivity";
3
3
  import type { Rpc } from "effect/rpc";
4
4
  import { SqlClient } from "effect/sql";
5
- import { invalidationKeys } from "@shivaedev/contract/keys.ts";
6
- import { CommandInvalidation, KeyScope } from "@shivaedev/contract/serverMetadata.ts";
5
+ import { invalidationKeys } from "@shivaedev/changes/keys.ts";
6
+ import { CurrentViewer } from "@shivaedev/contract/readPolicy.ts";
7
+ import { CommandInvalidation } from "@shivaedev/contract/serverMetadata.ts";
7
8
  import { ChangeObserver, invalidateOnCommit, transact } from "@shivaedev/sql/transact.ts";
8
9
  import { sessionKeyContext } from "#server/sessionKeys.ts";
9
10
 
10
- export function sessionCommandChanges<A, E, R>(effect: Effect.Effect<A, E, R>, rpc: Rpc.AnyWithProps, payload: unknown) {
11
- return Option.isSome(Context.getOption(rpc.annotations, KeyScope)) ? commandChanges(effect, rpc, payload) : effect;
12
- }
13
-
14
11
  export function commandChanges<A, E, R>(effect: Effect.Effect<A, E, R>, rpc: Rpc.AnyWithProps, payload: unknown) {
15
12
  const invalidates = Context.getOption(rpc.annotations, CommandInvalidation);
16
13
  if (Option.isNone(invalidates)) {
17
14
  return effect;
18
15
  }
19
- const declared = invalidates.value;
16
+ const declared = invalidates.value.invalidates;
20
17
  return Effect.gen(function* () {
21
18
  const context = yield* sessionKeyContext(rpc);
22
19
  const sql = yield* Effect.serviceOption(SqlClient.SqlClient);
@@ -36,7 +33,8 @@ export function commandChanges<A, E, R>(effect: Effect.Effect<A, E, R>, rpc: Rpc
36
33
  return observer(event);
37
34
  }),
38
35
  );
39
- const keys = invalidationKeys(declared(payload, result), context).filter((key) => !published.has(key));
36
+ const viewer = yield* CurrentViewer;
37
+ const keys = invalidationKeys(declared(payload, result, viewer), context).filter((key) => !published.has(key));
40
38
  if (keys.length > 0) {
41
39
  const announce = Option.isNone(sql)
42
40
  ? reactivity.value.invalidate(keys)
@@ -1,5 +1,6 @@
1
1
  import { Effect, Option } from "effect";
2
2
  import { HttpServerRequest, HttpServerResponse, HttpTraceContext } from "effect/http";
3
+ import * as HttpStatus from "effect/http/HttpStatus";
3
4
  import { RpcSerialization } from "effect/rpc";
4
5
  import { proxyAddresses, proxyMatches } from "./trustedProxy.ts";
5
6
  import { trustedProxyRanges as normalizedRanges } from "./trustedProxyRanges.ts";
@@ -40,7 +41,7 @@ export function loopbackOnly<E, R>(
40
41
  return (request: HttpServerRequest.HttpServerRequest) =>
41
42
  loopbackHost(request.headers.host) && Option.match(request.remoteAddress, { onNone: () => true, onSome: loopbackAddress })
42
43
  ? handler(request)
43
- : Effect.succeed(HttpServerResponse.text("Only loopback hosts are served", { status: 403 }));
44
+ : Effect.succeed(HttpServerResponse.text("Only loopback hosts are served", { status: HttpStatus.fromLiteral("Forbidden") }));
44
45
  }
45
46
  export function trustedProxyPeer(trustedProxy?: string): (address: string) => boolean {
46
47
  const addresses = trustedProxy === undefined ? undefined : proxyAddresses(trustedProxy);
@@ -86,7 +87,7 @@ export function localRpcGuard<E, R>(
86
87
  const contentType = request.headers["content-type"]?.split(";")[0]?.trim().toLowerCase();
87
88
  return allowed(request) && contentType === serialization.contentType
88
89
  ? yield* continueHttpTrace(effect, request)
89
- : HttpServerResponse.text("Local same-origin requests only", { status: 403 });
90
+ : HttpServerResponse.text("Local same-origin requests only", { status: HttpStatus.fromLiteral("Forbidden") });
90
91
  });
91
92
  }
92
93
 
@@ -1,11 +1,14 @@
1
1
  import { Effect, Layer, Option } from "effect";
2
2
  import { type HttpServerRequest, HttpServerResponse } from "effect/http";
3
+ import * as HttpStatus from "effect/http/HttpStatus";
3
4
  import type { RpcMiddleware } from "effect/rpc";
4
5
  import type { Permission } from "@shivaedev/access/permission.ts";
6
+ import { authorizeReads } from "@shivaedev/contract/readPolicy.ts";
7
+ import type { MissingReadPolicy, QueryReadDenied } from "@shivaedev/contract/readPolicyErrors.ts";
5
8
  import { type AuthUnavailable, Forbidden, type Unauthorized } from "@shivaedev/errors/taxonomy.ts";
6
9
  import { Identity, type SessionUser } from "#identity.ts";
7
10
  import { hasPermission, type permissionMiddleware, requirePermission } from "#permission.ts";
8
- import { sessionCommandChanges } from "#server/commandChanges.ts";
11
+ import { commandChanges } from "#server/commandChanges.ts";
9
12
  import { revalidateStream } from "./revalidateStream.ts";
10
13
  import { resolveSession, type SessionPolicy, type UserSessionShape, withSessionUser } from "./session.ts";
11
14
 
@@ -14,16 +17,17 @@ export function permissionLayer<TMiddleware, TSession extends UserSessionShape>(
14
17
  policy: SessionPolicy<TSession>,
15
18
  ) {
16
19
  const permission = middleware.permission;
17
- const guard: RpcMiddleware.RpcMiddleware<Identity | SessionUser, Unauthorized | AuthUnavailable | Forbidden, never> = (
18
- effect,
19
- { headers, rpc, payload },
20
- ) => {
20
+ const guard: RpcMiddleware.RpcMiddleware<
21
+ Identity | SessionUser,
22
+ Unauthorized | AuthUnavailable | Forbidden | MissingReadPolicy | QueryReadDenied,
23
+ never
24
+ > = (effect, { headers, rpc, payload }) => {
21
25
  const lookup = Effect.tap(resolveSession(policy, headers, rpc._tag), (session) =>
22
26
  Option.isSome(session) && !hasPermission(session.value.user, permission)
23
27
  ? Effect.fail(new Forbidden({ message: `Permission required: ${permission.name} (${permission.strength})` }))
24
28
  : Effect.void,
25
29
  );
26
- return sessionCommandChanges(effect, rpc, payload).pipe(
30
+ return Effect.flatMap(Identity, (viewer) => authorizeReads(commandChanges(effect, rpc, payload), { payload, rpc }, Option.some(viewer))).pipe(
27
31
  (invocation) => Effect.flatMap(Identity, ({ id }) => invocation.pipe(revalidateStream(policy, rpc, id, lookup))),
28
32
  (invocation) => Effect.andThen(requirePermission(permission), invocation),
29
33
  withSessionUser(policy, headers, rpc._tag),
@@ -34,7 +38,11 @@ export function permissionLayer<TMiddleware, TSession extends UserSessionShape>(
34
38
  function rejection(error: Unauthorized | Forbidden | AuthUnavailable) {
35
39
  return HttpServerResponse.empty({
36
40
  headers: { "cache-control": "private, no-store" },
37
- status: { AuthUnavailable: 503, Forbidden: 403, Unauthorized: 401 }[error._tag],
41
+ status: {
42
+ AuthUnavailable: HttpStatus.fromLiteral("ServiceUnavailable"),
43
+ Forbidden: HttpStatus.fromLiteral("Forbidden"),
44
+ Unauthorized: HttpStatus.fromLiteral("Unauthorized"),
45
+ }[error._tag],
38
46
  });
39
47
  }
40
48
 
@@ -2,6 +2,7 @@ import { Duration, Effect, Exit, Layer, Option } from "effect";
2
2
  import type { Headers } from "effect/http";
3
3
  import type { Permission } from "@shivaedev/access/permission.ts";
4
4
  import type { RoleSet } from "@shivaedev/access/roleSet.ts";
5
+ import { authorizeReads } from "@shivaedev/contract/readPolicy.ts";
5
6
  import { type AuthUnavailable, Forbidden, Unauthorized } from "@shivaedev/errors/taxonomy.ts";
6
7
  import {
7
8
  Identity,
@@ -12,7 +13,7 @@ import {
12
13
  type SessionUserWithProviderAccountsValue,
13
14
  } from "#identity.ts";
14
15
  import { Authenticated, AuthenticatedUser, AuthenticatedUserWithProviderAccounts, MaybeAuthenticated } from "#middleware.ts";
15
- import { sessionCommandChanges } from "#server/commandChanges.ts";
16
+ import { commandChanges } from "#server/commandChanges.ts";
16
17
  import { type OriginPolicy, originRequest } from "./origin.ts";
17
18
  import { resolveRole } from "./resolveRole.ts";
18
19
  import { revalidateStream } from "./revalidateStream.ts";
@@ -64,7 +65,7 @@ export function authenticatedLayer<TSession extends SessionShape>(policy: Sessio
64
65
  return yield* new Unauthorized({ message: "Authentication required" });
65
66
  }
66
67
  const id = yield* identified(session.value.user.id);
67
- return yield* sessionCommandChanges(effect, rpc, payload).pipe(
68
+ return yield* authorizeReads(commandChanges(effect, rpc, payload), { payload, rpc }, Option.some({ id })).pipe(
68
69
  revalidateStream(policy, rpc, id, resolveSession(policy, headers, rpc._tag)),
69
70
  Effect.provideService(Identity, { id }),
70
71
  Effect.annotateLogs({ userId: id }),
@@ -73,14 +74,14 @@ export function authenticatedLayer<TSession extends SessionShape>(policy: Sessio
73
74
  );
74
75
  }
75
76
  export function maybeAuthenticatedLayer<TSession extends SessionShape>(policy: SessionPolicy<TSession>): Layer.Layer<MaybeAuthenticated> {
76
- return Layer.succeed(MaybeAuthenticated, (effect, { headers, rpc }) =>
77
+ return Layer.succeed(MaybeAuthenticated, (effect, { headers, rpc, payload }) =>
77
78
  Effect.gen(function* () {
78
79
  const session = yield* resolveSession(policy, headers, rpc._tag);
79
80
  if (Option.isNone(session)) {
80
- return yield* Effect.provideService(effect, OptionalIdentity, Option.none());
81
+ return yield* Effect.provideService(authorizeReads(effect, { payload, rpc }, Option.none()), OptionalIdentity, Option.none());
81
82
  }
82
83
  const id = yield* identified(session.value.user.id);
83
- return yield* effect.pipe(
84
+ return yield* authorizeReads(effect, { payload, rpc }, Option.some({ id })).pipe(
84
85
  revalidateStream(policy, rpc, id, resolveSession(policy, headers, rpc._tag)),
85
86
  Effect.provideService(OptionalIdentity, Option.some({ id })),
86
87
  Effect.annotateLogs({ userId: id }),
@@ -109,7 +110,7 @@ export function withSessionUser<TSession extends UserSessionShape>(policy: Sessi
109
110
  }
110
111
  export function authenticatedUserLayer<TSession extends UserSessionShape>(policy: SessionPolicy<TSession>): Layer.Layer<AuthenticatedUser> {
111
112
  return Layer.succeed(AuthenticatedUser, (effect, { headers, rpc, payload }) =>
112
- sessionCommandChanges(effect, rpc, payload).pipe(
113
+ Effect.flatMap(Identity, (viewer) => authorizeReads(commandChanges(effect, rpc, payload), { payload, rpc }, Option.some(viewer))).pipe(
113
114
  (invocation) =>
114
115
  Effect.flatMap(Identity, ({ id }) => invocation.pipe(revalidateStream(policy, rpc, id, resolveSession(policy, headers, rpc._tag)))),
115
116
  withSessionUser(policy, headers, rpc._tag),
@@ -136,7 +137,7 @@ export function authenticatedUserWithProviderAccountsLayer<TSession extends Prov
136
137
  );
137
138
  const user = sessionProfile(session.value.user);
138
139
  yield* identified(id);
139
- return yield* sessionCommandChanges(effect, rpc, payload).pipe(
140
+ return yield* authorizeReads(commandChanges(effect, rpc, payload), { payload, rpc }, Option.some({ id })).pipe(
140
141
  revalidateStream(policy, rpc, id, resolveSession(policy, headers, rpc._tag)),
141
142
  Effect.provideService(Identity, { id }),
142
143
  Effect.provideService(SessionUser, user),
@@ -1,7 +1,9 @@
1
1
  import { Context, Effect, Option } from "effect";
2
2
  import type { Rpc } from "effect/rpc";
3
- import type { KeyContext } from "@shivaedev/contract/keys.ts";
4
- import { ChangesReads, KeyScope, type QueryReference } from "@shivaedev/contract/serverMetadata.ts";
3
+ import type { KeyContext } from "@shivaedev/changes/keys.ts";
4
+ import { querySubscription } from "@shivaedev/contract/querySubscription.ts";
5
+ import { CurrentViewer } from "@shivaedev/contract/readPolicy.ts";
6
+ import { ChangesQueries, KeyScope, type QueryReference } from "@shivaedev/contract/serverMetadata.ts";
5
7
  import { Identity } from "#identity.ts";
6
8
 
7
9
  export function sessionKeyContext(rpc: Pick<Rpc.AnyWithProps, "annotations">): Effect.Effect<KeyContext | undefined> {
@@ -17,9 +19,11 @@ export function sessionKeyContext(rpc: Pick<Rpc.AnyWithProps, "annotations">): E
17
19
  });
18
20
  }
19
21
 
20
- export function resolveChanges(rpc: Pick<Rpc.AnyWithProps, "annotations">, references: readonly QueryReference[]) {
21
- return Effect.map(sessionKeyContext(rpc), (context) => ({
22
- context,
23
- keys: Context.getUnsafe(rpc.annotations, ChangesReads)(references),
24
- }));
25
- }
22
+ export const resolveChanges = Effect.fnUntraced(function* (rpc: Pick<Rpc.AnyWithProps, "annotations">, references: readonly QueryReference[]) {
23
+ const identity = yield* Effect.serviceOption(Identity);
24
+ const current = yield* CurrentViewer;
25
+ const viewer = Option.orElse(identity, () => current);
26
+ const queries = yield* Context.getUnsafe(rpc.annotations, ChangesQueries).resolve(references);
27
+ const subscription = yield* querySubscription(queries, viewer);
28
+ return { context: yield* sessionKeyContext(rpc), subscription };
29
+ });