@shivaedev/platform 0.14.3 → 0.15.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.15.0 - 2026-10-18
4
+
5
+ ### Added
6
+
7
+ - Opt in to provider account IDs on `SessionUser.providerAccounts` by passing a `GetProviderAccounts` lookup to `betterAuthSessions`. Export `ProviderAccountValue` (`providerId`, `accountId`) and `SessionWithProviderAccounts` for typed access without querying Better Auth’s account table.
8
+
9
+ ## 0.14.4 - 2026-10-18
10
+
11
+ ### Fixed
12
+
13
+ - Align published framework dependencies with the current releases.
14
+
3
15
  ## 0.14.3 - 2026-10-18
4
16
 
5
17
  ### Fixed
package/README.md CHANGED
@@ -217,10 +217,32 @@ export const AccountHandlers = Account.toLayer({
217
217
  export const AccountServer = Layer.merge(AccountHandlers, authenticatedUserLayer(sessions));
218
218
  ```
219
219
 
220
- Here `sessions` is the application's policy from the previous example, with a Better Auth lookup that returns all three user fields. Merge `authenticatedUserLayer(sessions)` alongside the handler Layer when using `appHost`; the host continues to supply its id-only and optional middleware. A missing session fails with typed `Unauthorized`; rejected origins fail with `Forbidden`, and provider failures remain `AuthUnavailable`. The profile contains only id, name and email, without exposing the rest of the provider's user record. Handlers do not query the provider's user table.
220
+ Here `sessions` is the application's policy from the previous example, with a Better Auth lookup that returns all three user fields. Merge `authenticatedUserLayer(sessions)` alongside the handler Layer when using `appHost`; the host continues to supply its id-only and optional middleware. A missing session fails with typed `Unauthorized`; rejected origins fail with `Forbidden`, and provider failures remain `AuthUnavailable`. By default, the profile contains only id, name and email, without exposing the rest of the provider's user record. Handlers do not query the provider's user table.
221
221
 
222
222
  The starter's `notes.whoami` query returns this profile, and its note handlers use `SessionUser.id` for ownership. Its PostgreSQL/HTTP test checks concurrent users, anonymous requests and sign-out revocation.
223
223
 
224
+ #### Reading provider account IDs
225
+
226
+ Opt in to provider account IDs by passing Better Auth's account lookup as the second argument to `betterAuthSessions`. It runs after a session is found, using the same transport headers:
227
+
228
+ ```ts
229
+ const sessions = {
230
+ origin: trustedOrigins({ allow: ["https://app.example"], missing: "reject" }),
231
+ provider: betterAuthSessions(
232
+ (headers) => auth.api.getSession({ headers }),
233
+ (headers) => auth.api.listUserAccounts({ headers }),
234
+ ),
235
+ };
236
+
237
+ const githubAccount = Effect.map(SessionUser, (user) =>
238
+ user.providerAccounts?.find((account) => account.providerId === "github"),
239
+ );
240
+ ```
241
+
242
+ Use `authenticatedUserLayer(sessions)` as above. `SessionUserValue.providerAccounts` is an optional readonly array of `ProviderAccountValue`, each containing only `{ providerId: string, accountId: string }`. GitHub's numeric user ID is represented as a string, for example `{ providerId: "github", accountId: "123" }`; it is not Better Auth's account-row id. A user without a GitHub account has no matching entry. Without the second lookup, the profile omits `providerAccounts`. No application SQL against Better Auth's `account` table is needed.
243
+
244
+ An account lookup failure follows the same `AuthUnavailable` path as a session lookup failure. The starter's social-session story uses real PostgreSQL, GitHub OAuth responses from a local provider fixture, and Platform's HTTP host: GitHub sign-in exposes its account ID through native RPC, email sign-up has no GitHub entry, sign-out rejects access, and an account lookup failure stays distinct from a missing session.
245
+
224
246
  ### Transport headers and request ids
225
247
 
226
248
  Session resolution reads `HttpServerRequest`: the HTTP POST or WebSocket upgrade request. Credentials and Origin supplied inside an RPC message cannot replace those transport headers. An application-owned middleware can use `transportHeaders(rpcHeaders)` for the same source of headers.
@@ -464,11 +486,11 @@ Import the module that defines the name; there is no package-root entry. Paths b
464
486
  | `appHost.ts` | `appHost({ group, handlers, services, migrations?, sessions?, policy?, rpcPath?, assets?, routes?, config? })` or `appHost({ application, migrations, config? })`, `appDatabase({ migrations, config? })`, `AppChanges`, `AppHostOptions`, `AppHttpHostOptions`, `AppLocalHostOptions`, `AppDatabaseOptions`: scoped HTTP and PostgreSQL composition with loopback defaults and optional proxy trust. |
465
487
  | `errors/taxonomy.ts` | `NotFound`, `Unauthorized`, `Forbidden`, `BadRequest`, `Conflict`, `PreconditionFailed`, `TooManyRequests`, `AuthUnavailable`, `InternalServerError`, `ServiceUnavailable`: Schema tagged error classes with a `message`; `BadRequest` and `Conflict` also accept an optional `field`. |
466
488
  | `errors/rejected-field.ts` | `rejectedField(unknown): Option<RejectedField>`; `RejectedField` is `{ field: string, message: string }`. |
467
- | `rpc/identity.ts` | `RequestId`: string service. `Identity`: `IdentityValue`, `{ id: string }`. `OptionalIdentity`: `Option<IdentityValue>`. `SessionUser`: `SessionUserValue`, `{ id, name, email }`. |
489
+ | `rpc/identity.ts` | `RequestId`: string service. `Identity`: `IdentityValue`, `{ id: string }`. `OptionalIdentity`: `Option<IdentityValue>`. `SessionUser`: `SessionUserValue`, `{ id, name, email, providerAccounts? }`; `ProviderAccountValue`: `{ providerId, accountId }`. |
468
490
  | `rpc/middleware.ts` | `RequestTracing`, `Authenticated`, `AuthenticatedUser`, `MaybeAuthenticated`: native RPC middleware declarations. |
469
491
  | `rpc-server/boundary.ts` | `rpcBoundary(schema, { unexpected, message? })`; `RpcBoundaryOptions<Error>`: declared failures pass through, unexpected failures become one declared rejection. |
470
492
  | `rpc-server/session.ts` | `authenticatedLayer(policy)`, `maybeAuthenticatedLayer(policy)`, `resolveSession(policy, headers, rpc)`; `SessionShape`, `SessionProvider<Session>`, `SessionPolicy<Session>`. `authenticatedUserLayer(policy)` requires `UserSessionShape` and implements `AuthenticatedUser`. |
471
- | `rpc-server/adapters/better-auth-sessions.ts` | `betterAuthSessions(getSession)`; `GetSession<Session>` is a Promise lookup returning `Session \| null`. |
493
+ | `rpc-server/adapters/better-auth-sessions.ts` | `betterAuthSessions(getSession, getProviderAccounts?)`; `GetSession<Session>` returns `Promise<Session \| null>`, `GetProviderAccounts` returns provider/id pairs, and `SessionWithProviderAccounts<Session>` describes an enriched session. |
472
494
  | `rpc-server/origin.ts` | `trustedOrigins({ allow, missing })`, `originRequest(headers, rpc)`; `OriginPolicy`, `OriginRequest`, `TrustedOriginsOptions`. |
473
495
  | `rpc-server/local.ts` | `localRpcGuard(effect)`: HTTP RPC guard using native request and serialization services; `loopbackOnly(handler)`, `sameOrigin(request)`, `trustedProxyPeer(trustedProxy?)`, `trustedProxyRanges(trustedProxy?)`. |
474
496
  | `rpc-server/transport.ts` | `transportHeaders(rpcHeaders)`: Effect returning the headers used for a transport-level decision. |
@@ -505,7 +527,7 @@ Install the optional peers for the selected integration:
505
527
  | `testing/vitest.ts` | `@effect/vitest`, `@shivaedev/effect-prisma`, `@shivaedev/effect-trpc`, `@trpc/server` |
506
528
 
507
529
  - The package declares Node 24 or newer and uses the Effect version in its peer manifest.
508
- - Keep the auth provider's configuration, cookie settings and resource authorization in the application. The session adapter takes only a lookup function and returns a session result; it does not write provider refresh cookies into RPC responses.
530
+ - 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.
509
531
  - Without an `HttpServerRequest`, `transportHeaders` falls back to the supplied RPC headers. An application using another transport must decide what headers it can trust.
510
532
  - Add tracing last on the native group, as in the example, so it wraps the authentication middleware too. Middleware outside that tracing boundary is responsible for its own diagnostics.
511
533
  - Redaction recognizes common shapes. Keep secrets out of messages and extend the key predicate for application-specific sensitive fields.
@@ -11,9 +11,14 @@ export declare class Identity extends Identity_base {
11
11
  declare const OptionalIdentity_base: Context.ServiceClass<OptionalIdentity, "@shivaedev/platform/rpc/OptionalIdentity", Option.Option<IdentityValue>>;
12
12
  export declare class OptionalIdentity extends OptionalIdentity_base {
13
13
  }
14
+ export interface ProviderAccountValue {
15
+ readonly accountId: string;
16
+ readonly providerId: string;
17
+ }
14
18
  export interface SessionUserValue extends IdentityValue {
15
19
  readonly email: string;
16
20
  readonly name: string;
21
+ readonly providerAccounts?: readonly ProviderAccountValue[];
17
22
  }
18
23
  declare const SessionUser_base: Context.ServiceClass<SessionUser, "@shivaedev/platform/rpc/SessionUser", SessionUserValue>;
19
24
  export declare class SessionUser extends SessionUser_base {
@@ -1 +1 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/rpc/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;;AAC9C,qBAAa,SAAU,SAAQ,cAAyE;CAAG;AAC3G,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACpB;;AACD,qBAAa,QAAS,SAAQ,aAA8E;CAAG;;AAC/G,qBAAa,gBAAiB,SAAQ,qBAA6G;CAAG;AACtJ,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;;AACD,qBAAa,WAAY,SAAQ,gBAAuF;CAAG"}
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/rpc/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;;AAC9C,qBAAa,SAAU,SAAQ,cAAyE;CAAG;AAC3G,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACpB;;AACD,qBAAa,QAAS,SAAQ,aAA8E;CAAG;;AAC/G,qBAAa,gBAAiB,SAAQ,qBAA6G;CAAG;AACtJ,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AACD,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;CAC5D;;AACD,qBAAa,WAAY,SAAQ,gBAAuF;CAAG"}
@@ -1 +1 @@
1
- {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/rpc/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,QAAQ,CAAC;AAC9C,MAAM,OAAO,SAAU,SAAQ,OAAO,CAAC,OAAO,EAAqB,CAAC,mCAAmC,CAAC;CAAG;AAI3G,MAAM,OAAO,QAAS,SAAQ,OAAO,CAAC,OAAO,EAA2B,CAAC,kCAAkC,CAAC;CAAG;AAC/G,MAAM,OAAO,gBAAiB,SAAQ,OAAO,CAAC,OAAO,EAAkD,CAAC,0CAA0C,CAAC;CAAG;AAKtJ,MAAM,OAAO,WAAY,SAAQ,OAAO,CAAC,OAAO,EAAiC,CAAC,qCAAqC,CAAC;CAAG"}
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/rpc/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,QAAQ,CAAC;AAC9C,MAAM,OAAO,SAAU,SAAQ,OAAO,CAAC,OAAO,EAAqB,CAAC,mCAAmC,CAAC;CAAG;AAI3G,MAAM,OAAO,QAAS,SAAQ,OAAO,CAAC,OAAO,EAA2B,CAAC,kCAAkC,CAAC;CAAG;AAC/G,MAAM,OAAO,gBAAiB,SAAQ,OAAO,CAAC,OAAO,EAAkD,CAAC,0CAA0C,CAAC;CAAG;AAUtJ,MAAM,OAAO,WAAY,SAAQ,OAAO,CAAC,OAAO,EAAiC,CAAC,qCAAqC,CAAC;CAAG"}
@@ -1,4 +1,12 @@
1
+ import type { ProviderAccountValue } from "#rpc/identity.ts";
1
2
  import type { SessionProvider, SessionShape } from "#rpc-server/session.ts";
2
3
  export type GetSession<TSession extends SessionShape> = (headers: globalThis.Headers) => Promise<TSession | null>;
4
+ export type GetProviderAccounts = (headers: globalThis.Headers) => Promise<readonly ProviderAccountValue[]>;
5
+ export type SessionWithProviderAccounts<TSession extends SessionShape> = TSession & {
6
+ readonly user: TSession["user"] & {
7
+ readonly providerAccounts: readonly ProviderAccountValue[];
8
+ };
9
+ };
3
10
  export declare function betterAuthSessions<TSession extends SessionShape>(getSession: GetSession<TSession>): SessionProvider<TSession>;
11
+ export declare function betterAuthSessions<TSession extends SessionShape>(getSession: GetSession<TSession>, getProviderAccounts: GetProviderAccounts): SessionProvider<SessionWithProviderAccounts<TSession>>;
4
12
  //# sourceMappingURL=betterAuthSessions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"betterAuthSessions.d.ts","sourceRoot":"","sources":["../../../../src/server/rpc-server/adapters/betterAuthSessions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC5E,MAAM,MAAM,UAAU,CAAC,QAAQ,SAAS,YAAY,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAOlH,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,YAAY,EAAE,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,eAAe,CAAC,QAAQ,CAAC,CAQ7H"}
1
+ {"version":3,"file":"betterAuthSessions.d.ts","sourceRoot":"","sources":["../../../../src/server/rpc-server/adapters/betterAuthSessions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC5E,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,SAAS,oBAAoB,EAAE,CAAA;KAAE,CAAC;CACjG,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"}
@@ -4,9 +4,20 @@ import { redact } from "#rpc-server/redact.ts";
4
4
  function unavailable(cause) {
5
5
  return Effect.andThen(Effect.logError("Authentication provider failed", redact(cause)), Effect.fail(new AuthUnavailable({ message: "Authentication is temporarily unavailable" })));
6
6
  }
7
- export function betterAuthSessions(getSession) {
7
+ export function betterAuthSessions(getSession, getProviderAccounts) {
8
8
  const betterAuthSession = Effect.fn("PlatformRpc.betterAuthSession")(function* (headers) {
9
- const session = yield* Effect.tryPromise(() => getSession(new globalThis.Headers(headers))).pipe(Effect.catch((error) => unavailable(error.cause)));
9
+ const session = yield* Effect.tryPromise(async () => {
10
+ const transport = new globalThis.Headers(headers);
11
+ const resolved = await getSession(transport);
12
+ if (resolved === null || getProviderAccounts === undefined) {
13
+ return resolved;
14
+ }
15
+ const accounts = await getProviderAccounts(transport);
16
+ return {
17
+ ...resolved,
18
+ user: { ...resolved.user, providerAccounts: accounts.map(({ accountId, providerId }) => ({ accountId, providerId })) },
19
+ };
20
+ }).pipe(Effect.catch((error) => unavailable(error.cause)));
10
21
  return Option.fromNullishOr(session);
11
22
  });
12
23
  return { get: betterAuthSession };
@@ -1 +1 @@
1
- {"version":3,"file":"betterAuthSessions.js","sourceRoot":"","sources":["../../../../src/server/rpc-server/adapters/betterAuthSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAG/C,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;AACD,MAAM,UAAU,kBAAkB,CAAgC,UAAgC;IACjG,MAAM,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAC,+BAA+B,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAwB;QACvG,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAC/F,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CACjD,CAAC;QACF,OAAO,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"betterAuthSessions.js","sourceRoot":"","sources":["../../../../src/server/rpc-server/adapters/betterAuthSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAO/C,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,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;YACnD,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAClD,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC;YAC7C,IAAI,QAAQ,KAAK,IAAI,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;gBAC5D,OAAO,QAAQ,CAAC;YACjB,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,SAAS,CAAC,CAAC;YACtD,OAAO;gBACN,GAAG,QAAQ;gBACX,IAAI,EAAE,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE;aACtH,CAAC;QACH,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3D,OAAO,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,CAAC;AACnC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/server/rpc-server/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,KAAK,eAAe,EAAE,SAAS,EAAgB,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAA2C,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,KAAK,YAAY,EAAiB,MAAM,aAAa,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,IAAI,EAAE;QACd,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;KACpB,CAAC;CACF;AACD,MAAM,WAAW,eAAe,CAAC,QAAQ,SAAS,YAAY;IAC7D,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC;CACpG;AACD,MAAM,WAAW,aAAa,CAAC,QAAQ,SAAS,YAAY;IAC3D,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;CAC7C;AACD,eAAO,MAAM,cAAc,EAAE,CAAC,QAAQ,SAAS,YAAY,EAC1D,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAC/B,OAAO,EAAE,OAAO,CAAC,OAAO,EACxB,GAAG,EAAE,MAAM,KACP,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,SAAS,CAQrE,CAAC;AAIH,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAW7H;AACD,wBAAgB,uBAAuB,CAAC,QAAQ,SAAS,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAWvI;AACD,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACrD,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;CAChC;AACD,wBAAgB,sBAAsB,CAAC,QAAQ,SAAS,gBAAgB,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAgBzI"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/server/rpc-server/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,KAAK,eAAe,EAAE,SAAS,EAAgB,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAA2C,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,KAAK,YAAY,EAAiB,MAAM,aAAa,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,IAAI,EAAE;QACd,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;KACpB,CAAC;CACF;AACD,MAAM,WAAW,eAAe,CAAC,QAAQ,SAAS,YAAY;IAC7D,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC;CACpG;AACD,MAAM,WAAW,aAAa,CAAC,QAAQ,SAAS,YAAY;IAC3D,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;CAC7C;AACD,eAAO,MAAM,cAAc,EAAE,CAAC,QAAQ,SAAS,YAAY,EAC1D,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAC/B,OAAO,EAAE,OAAO,CAAC,OAAO,EACxB,GAAG,EAAE,MAAM,KACP,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,SAAS,CAQrE,CAAC;AAIH,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAW7H;AACD,wBAAgB,uBAAuB,CAAC,QAAQ,SAAS,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAWvI;AACD,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACrD,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;CAChC;AACD,wBAAgB,sBAAsB,CAAC,QAAQ,SAAS,gBAAgB,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAuBzI"}
@@ -40,9 +40,16 @@ export function authenticatedUserLayer(policy) {
40
40
  if (Option.isNone(session)) {
41
41
  return yield* new Unauthorized({ message: "Authentication required" });
42
42
  }
43
- const { name, email } = session.value.user;
43
+ const { name, email, providerAccounts } = session.value.user;
44
44
  const id = yield* identified(session.value.user.id);
45
- return yield* effect.pipe(Effect.provideService(Identity, { id }), Effect.provideService(SessionUser, { email, id, name }), Effect.annotateLogs({ userId: id }));
45
+ return yield* effect.pipe(Effect.provideService(Identity, { id }), Effect.provideService(SessionUser, {
46
+ email,
47
+ id,
48
+ name,
49
+ ...(providerAccounts === undefined
50
+ ? {}
51
+ : { providerAccounts: providerAccounts.map(({ accountId, providerId }) => ({ accountId, providerId })) }),
52
+ }), Effect.annotateLogs({ userId: id }));
46
53
  }));
47
54
  }
48
55
  //# sourceMappingURL=session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/server/rpc-server/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,EAAwB,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAyB,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAqB,aAAa,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAazD,MAAM,CAAC,MAAM,cAAc,GAIgD,MAAM,CAAC,EAAE,CAAC,4BAA4B,CAAC,CAAC,QAAQ,CAAC,EAE1H,MAA+B,EAAE,OAAwB,EAAE,GAAW;IACvE,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,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AACH,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,EAAE,EAAE,CAChE,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,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACzG,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,EAAE,EAAE,CACrE,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,MAAM,EAAE,gBAAgB,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,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,CAAC,MAAM,CAAC,cAAc,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9H,CAAC,CAAC,CACF,CAAC;AACH,CAAC;AAID,MAAM,UAAU,sBAAsB,CAAoC,MAA+B;IACxG,OAAO,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CACpE,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,IAAI,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;QAC3C,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,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EACvD,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CACnC,CAAC;IACH,CAAC,CAAC,CACF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/server/rpc-server/session.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shivaedev/platform",
3
- "version": "0.14.3",
3
+ "version": "0.15.0",
4
4
  "description": "Opinionated Effect application infrastructure for ShivaeDev services",
5
5
  "homepage": "https://github.com/ShivaeDev/platform/tree/main/packages/platform#readme",
6
6
  "bugs": {
@@ -373,7 +373,7 @@
373
373
  ],
374
374
  "dependencies": {
375
375
  "@shivaedev/effect-contract": "0.5.1",
376
- "@shivaedev/effect-sql": "0.5.0",
376
+ "@shivaedev/effect-sql": "0.5.1",
377
377
  "@shivaedev/types": "0.2.1"
378
378
  },
379
379
  "devDependencies": {
@@ -387,9 +387,9 @@
387
387
  "@prisma-next/sql-orm-client": "0.16.0",
388
388
  "@prisma-next/target-postgres": "0.16.0",
389
389
  "@shivaedev/effect-prisma": "0.9.2",
390
- "@shivaedev/effect-trpc": "0.7.1",
391
- "@shivaedev/quality": "0.23.0",
392
- "@shivaedev/test-story": "0.6.0",
390
+ "@shivaedev/effect-trpc": "0.7.2",
391
+ "@shivaedev/quality": "0.24.0",
392
+ "@shivaedev/test-story": "0.7.0",
393
393
  "@trpc/client": "11.19.0",
394
394
  "@trpc/server": "11.19.0",
395
395
  "@types/node": "24.19.2",
@@ -406,7 +406,7 @@
406
406
  "@effect/vitest": "4.0.4",
407
407
  "@prisma-next/sql-orm-client": "0.16.0",
408
408
  "@shivaedev/effect-prisma": "0.9.2",
409
- "@shivaedev/effect-trpc": "0.7.1",
409
+ "@shivaedev/effect-trpc": "0.7.2",
410
410
  "@trpc/server": "11.19.0",
411
411
  "better-auth": "1.7.7",
412
412
  "effect": "4.0.4"
@@ -5,8 +5,13 @@ export interface IdentityValue {
5
5
  }
6
6
  export class Identity extends Context.Service<Identity, IdentityValue>()("@shivaedev/platform/rpc/Identity") {}
7
7
  export class OptionalIdentity extends Context.Service<OptionalIdentity, Option.Option<IdentityValue>>()("@shivaedev/platform/rpc/OptionalIdentity") {}
8
+ export interface ProviderAccountValue {
9
+ readonly accountId: string;
10
+ readonly providerId: string;
11
+ }
8
12
  export interface SessionUserValue extends IdentityValue {
9
13
  readonly email: string;
10
14
  readonly name: string;
15
+ readonly providerAccounts?: readonly ProviderAccountValue[];
11
16
  }
12
17
  export class SessionUser extends Context.Service<SessionUser, SessionUserValue>()("@shivaedev/platform/rpc/SessionUser") {}
@@ -1,20 +1,39 @@
1
1
  import { Effect, Option } from "effect";
2
2
  import type { Headers } from "effect/http";
3
3
  import { AuthUnavailable } from "#errors/taxonomy.ts";
4
+ import type { ProviderAccountValue } from "#rpc/identity.ts";
4
5
  import { redact } from "#rpc-server/redact.ts";
5
6
  import type { SessionProvider, SessionShape } from "#rpc-server/session.ts";
6
7
  export type GetSession<TSession extends SessionShape> = (headers: globalThis.Headers) => Promise<TSession | null>;
8
+ export type GetProviderAccounts = (headers: globalThis.Headers) => Promise<readonly ProviderAccountValue[]>;
9
+ export type SessionWithProviderAccounts<TSession extends SessionShape> = TSession & {
10
+ readonly user: TSession["user"] & { readonly providerAccounts: readonly ProviderAccountValue[] };
11
+ };
7
12
  function unavailable(cause: unknown) {
8
13
  return Effect.andThen(
9
14
  Effect.logError("Authentication provider failed", redact(cause)),
10
15
  Effect.fail(new AuthUnavailable({ message: "Authentication is temporarily unavailable" })),
11
16
  );
12
17
  }
13
- export function betterAuthSessions<TSession extends SessionShape>(getSession: GetSession<TSession>): SessionProvider<TSession> {
18
+ export function betterAuthSessions<TSession extends SessionShape>(getSession: GetSession<TSession>): SessionProvider<TSession>;
19
+ export function betterAuthSessions<TSession extends SessionShape>(
20
+ getSession: GetSession<TSession>,
21
+ getProviderAccounts: GetProviderAccounts,
22
+ ): SessionProvider<SessionWithProviderAccounts<TSession>>;
23
+ export function betterAuthSessions<TSession extends SessionShape>(getSession: GetSession<TSession>, getProviderAccounts?: GetProviderAccounts) {
14
24
  const betterAuthSession = Effect.fn("PlatformRpc.betterAuthSession")(function* (headers: Headers.Headers) {
15
- const session = yield* Effect.tryPromise(() => getSession(new globalThis.Headers(headers))).pipe(
16
- Effect.catch((error) => unavailable(error.cause)),
17
- );
25
+ const session = yield* Effect.tryPromise(async () => {
26
+ const transport = new globalThis.Headers(headers);
27
+ const resolved = await getSession(transport);
28
+ if (resolved === null || getProviderAccounts === undefined) {
29
+ return resolved;
30
+ }
31
+ const accounts = await getProviderAccounts(transport);
32
+ return {
33
+ ...resolved,
34
+ user: { ...resolved.user, providerAccounts: accounts.map(({ accountId, providerId }) => ({ accountId, providerId })) },
35
+ };
36
+ }).pipe(Effect.catch((error) => unavailable(error.cause)));
18
37
  return Option.fromNullishOr(session);
19
38
  });
20
39
  return { get: betterAuthSession };
@@ -67,11 +67,18 @@ export function authenticatedUserLayer<TSession extends UserSessionShape>(policy
67
67
  if (Option.isNone(session)) {
68
68
  return yield* new Unauthorized({ message: "Authentication required" });
69
69
  }
70
- const { name, email } = session.value.user;
70
+ const { name, email, providerAccounts } = session.value.user;
71
71
  const id = yield* identified(session.value.user.id);
72
72
  return yield* effect.pipe(
73
73
  Effect.provideService(Identity, { id }),
74
- Effect.provideService(SessionUser, { email, id, name }),
74
+ Effect.provideService(SessionUser, {
75
+ email,
76
+ id,
77
+ name,
78
+ ...(providerAccounts === undefined
79
+ ? {}
80
+ : { providerAccounts: providerAccounts.map(({ accountId, providerId }) => ({ accountId, providerId })) }),
81
+ }),
75
82
  Effect.annotateLogs({ userId: id }),
76
83
  );
77
84
  }),