@yielded/auth 0.1.0-beta.1 → 0.1.0-beta.3

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/README.md CHANGED
@@ -14,5 +14,5 @@ caller’s Scope; credentials stay outside public results and telemetry.
14
14
  Optional database, platform, browser, and OAuth adapters have separate exports.
15
15
  The root import does not load their peer dependencies. Effect is supplied by the host.
16
16
 
17
- See the [authentication guide](https://github.com/danieljvdm/effect-auth/blob/main/docs/guide/authentication.md)
18
- and [consumer examples](https://github.com/danieljvdm/effect-auth/tree/main/examples/auth).
17
+ See the [authentication guide](https://github.com/yielded-dev/auth/blob/main/docs/guide/authentication.md)
18
+ and [consumer examples](https://github.com/yielded-dev/auth/tree/main/examples/auth).
@@ -699,11 +699,9 @@ declare const makeOAuthAccountsServices: <S extends AnySQLiteTable<{
699
699
  readonly invalidation: SessionInvalidationWindow;
700
700
  readonly nowMillis: number;
701
701
  }, prepare: PrepareOAuthCommit<{
702
- readonly _tag: "Ambiguous";
703
- } | {
704
702
  readonly _tag: "Rejected";
705
703
  } | {
706
- readonly _tag: "Conflict";
704
+ readonly _tag: "Ambiguous";
707
705
  } | {
708
706
  readonly _tag: "Cancelled";
709
707
  } | {
@@ -727,6 +725,8 @@ declare const makeOAuthAccountsServices: <S extends AnySQLiteTable<{
727
725
  };
728
726
  };
729
727
  readonly changed: boolean;
728
+ } | {
729
+ readonly _tag: "Conflict";
730
730
  }, A>) => Effect.Effect<PreparedCommit<A>, OAuthUnavailable>;
731
731
  readonly inspectUnlink: (input: {
732
732
  readonly moduleId: string & import("effect/Brand").Brand<"effect-auth/OAuthModuleId">;
@@ -1281,14 +1281,14 @@ declare const makeOAuthAccountsServices: <S extends AnySQLiteTable<{
1281
1281
  };
1282
1282
  }) => Effect.Effect<{
1283
1283
  readonly _tag: "Rejected";
1284
+ } | {
1285
+ readonly _tag: "Conflict";
1284
1286
  } | {
1285
1287
  readonly _tag: "Target";
1286
1288
  readonly cohortGeneration: string & import("effect/Brand").Brand<"effect-auth/SecurityRevision">;
1287
1289
  } | {
1288
1290
  readonly _tag: "Quarantine";
1289
1291
  readonly cohortGeneration: string & import("effect/Brand").Brand<"effect-auth/SecurityRevision">;
1290
- } | {
1291
- readonly _tag: "Conflict";
1292
1292
  }, OAuthUnavailable>;
1293
1293
  readonly settle: <A>(input: {
1294
1294
  readonly claim: OAuthConnectedClaim;
@@ -1296,13 +1296,13 @@ declare const makeOAuthAccountsServices: <S extends AnySQLiteTable<{
1296
1296
  readonly authorization: OAuthConnectedActionAuthorization;
1297
1297
  readonly nowMillis: number;
1298
1298
  }, prepare: PrepareOAuthCommit<{
1299
- readonly _tag: "Ambiguous";
1300
- } | {
1301
1299
  readonly _tag: "Rejected";
1302
1300
  } | {
1303
- readonly _tag: "Conflict";
1301
+ readonly _tag: "Ambiguous";
1304
1302
  } | {
1305
1303
  readonly _tag: "Cancelled";
1304
+ } | {
1305
+ readonly _tag: "Conflict";
1306
1306
  } | {
1307
1307
  readonly _tag: "Connected";
1308
1308
  readonly grant: {
@@ -221,12 +221,12 @@ declare const makeOAuthAccountsServices: <S extends AnyMySqlTable<{
221
221
  readonly nowMillis: number;
222
222
  }, prepare: PrepareOAuthCommit<{
223
223
  readonly _tag: "Rejected";
224
+ } | {
225
+ readonly _tag: "Ambiguous";
224
226
  } | {
225
227
  readonly _tag: "Conflict";
226
228
  } | {
227
229
  readonly _tag: "Cancelled";
228
- } | {
229
- readonly _tag: "Ambiguous";
230
230
  } | {
231
231
  readonly _tag: "Linked";
232
232
  readonly credential: {
@@ -592,6 +592,8 @@ declare const makeOAuthAccountsServices: <S extends AnyMySqlTable<{
592
592
  readonly flow: OAuthConnectedPendingFlow;
593
593
  readonly authorization: OAuthConnectedActionAuthorization;
594
594
  }, prepare: PrepareOAuthCommit<{
595
+ readonly _tag: "Rejected";
596
+ } | {
595
597
  readonly _tag: "Issued";
596
598
  readonly flow: {
597
599
  readonly context: {
@@ -683,8 +685,6 @@ declare const makeOAuthAccountsServices: <S extends AnyMySqlTable<{
683
685
  };
684
686
  readonly retentionUntilMillis: number;
685
687
  };
686
- } | {
687
- readonly _tag: "Rejected";
688
688
  }, A>) => import("effect/Effect").Effect<PreparedCommit<A>, OAuthUnavailable, never>;
689
689
  readonly preflight: (input: OAuthConnectedAccess) => import("effect/Effect").Effect<OAuthConnectedPendingFlow | undefined, OAuthUnavailable>;
690
690
  readonly claim: <A>(input: {
@@ -818,12 +818,12 @@ declare const makeOAuthAccountsServices: <S extends AnyMySqlTable<{
818
818
  readonly nowMillis: number;
819
819
  }, prepare: PrepareOAuthCommit<{
820
820
  readonly _tag: "Rejected";
821
+ } | {
822
+ readonly _tag: "Ambiguous";
821
823
  } | {
822
824
  readonly _tag: "Conflict";
823
825
  } | {
824
826
  readonly _tag: "Cancelled";
825
- } | {
826
- readonly _tag: "Ambiguous";
827
827
  } | {
828
828
  readonly _tag: "Connected";
829
829
  readonly grant: {
@@ -220,12 +220,12 @@ declare const makeOAuthAccountsServices: <S extends AnyPgTable<{
220
220
  readonly nowMillis: number;
221
221
  }, prepare: PrepareOAuthCommit<{
222
222
  readonly _tag: "Rejected";
223
+ } | {
224
+ readonly _tag: "Ambiguous";
223
225
  } | {
224
226
  readonly _tag: "Conflict";
225
227
  } | {
226
228
  readonly _tag: "Cancelled";
227
- } | {
228
- readonly _tag: "Ambiguous";
229
229
  } | {
230
230
  readonly _tag: "Linked";
231
231
  readonly credential: {
@@ -591,6 +591,8 @@ declare const makeOAuthAccountsServices: <S extends AnyPgTable<{
591
591
  readonly flow: OAuthConnectedPendingFlow;
592
592
  readonly authorization: OAuthConnectedActionAuthorization;
593
593
  }, prepare: PrepareOAuthCommit<{
594
+ readonly _tag: "Rejected";
595
+ } | {
594
596
  readonly _tag: "Issued";
595
597
  readonly flow: {
596
598
  readonly context: {
@@ -682,8 +684,6 @@ declare const makeOAuthAccountsServices: <S extends AnyPgTable<{
682
684
  };
683
685
  readonly retentionUntilMillis: number;
684
686
  };
685
- } | {
686
- readonly _tag: "Rejected";
687
687
  }, A>) => import("effect/Effect").Effect<PreparedCommit<A>, OAuthUnavailable, never>;
688
688
  readonly preflight: (input: OAuthConnectedAccess) => import("effect/Effect").Effect<OAuthConnectedPendingFlow | undefined, OAuthUnavailable>;
689
689
  readonly claim: <A>(input: {
@@ -817,12 +817,12 @@ declare const makeOAuthAccountsServices: <S extends AnyPgTable<{
817
817
  readonly nowMillis: number;
818
818
  }, prepare: PrepareOAuthCommit<{
819
819
  readonly _tag: "Rejected";
820
+ } | {
821
+ readonly _tag: "Ambiguous";
820
822
  } | {
821
823
  readonly _tag: "Conflict";
822
824
  } | {
823
825
  readonly _tag: "Cancelled";
824
- } | {
825
- readonly _tag: "Ambiguous";
826
826
  } | {
827
827
  readonly _tag: "Connected";
828
828
  readonly grant: {
@@ -754,11 +754,9 @@ declare const makeOAuthAccountsServices: <S extends AnySQLiteTable<{
754
754
  readonly invalidation: SessionInvalidationWindow;
755
755
  readonly nowMillis: number;
756
756
  }, prepare: PrepareOAuthCommit<{
757
- readonly _tag: "Ambiguous";
758
- } | {
759
757
  readonly _tag: "Rejected";
760
758
  } | {
761
- readonly _tag: "Conflict";
759
+ readonly _tag: "Ambiguous";
762
760
  } | {
763
761
  readonly _tag: "Cancelled";
764
762
  } | {
@@ -782,6 +780,8 @@ declare const makeOAuthAccountsServices: <S extends AnySQLiteTable<{
782
780
  };
783
781
  };
784
782
  readonly changed: boolean;
783
+ } | {
784
+ readonly _tag: "Conflict";
785
785
  }, A>) => Effect.Effect<PreparedCommit<A>, OAuthUnavailable>;
786
786
  readonly inspectUnlink: (input: {
787
787
  readonly moduleId: string & import("effect/Brand").Brand<"effect-auth/OAuthModuleId">;
@@ -1336,14 +1336,14 @@ declare const makeOAuthAccountsServices: <S extends AnySQLiteTable<{
1336
1336
  };
1337
1337
  }) => Effect.Effect<{
1338
1338
  readonly _tag: "Rejected";
1339
+ } | {
1340
+ readonly _tag: "Conflict";
1339
1341
  } | {
1340
1342
  readonly _tag: "Target";
1341
1343
  readonly cohortGeneration: string & import("effect/Brand").Brand<"effect-auth/SecurityRevision">;
1342
1344
  } | {
1343
1345
  readonly _tag: "Quarantine";
1344
1346
  readonly cohortGeneration: string & import("effect/Brand").Brand<"effect-auth/SecurityRevision">;
1345
- } | {
1346
- readonly _tag: "Conflict";
1347
1347
  }, OAuthUnavailable>;
1348
1348
  readonly settle: <A>(input: {
1349
1349
  readonly claim: OAuthConnectedClaim;
@@ -1351,13 +1351,13 @@ declare const makeOAuthAccountsServices: <S extends AnySQLiteTable<{
1351
1351
  readonly authorization: OAuthConnectedActionAuthorization;
1352
1352
  readonly nowMillis: number;
1353
1353
  }, prepare: PrepareOAuthCommit<{
1354
- readonly _tag: "Ambiguous";
1355
- } | {
1356
1354
  readonly _tag: "Rejected";
1357
1355
  } | {
1358
- readonly _tag: "Conflict";
1356
+ readonly _tag: "Ambiguous";
1359
1357
  } | {
1360
1358
  readonly _tag: "Cancelled";
1359
+ } | {
1360
+ readonly _tag: "Conflict";
1361
1361
  } | {
1362
1362
  readonly _tag: "Connected";
1363
1363
  readonly grant: {
@@ -699,12 +699,12 @@ declare const makeOAuthAccountsServices: <S extends AnySQLiteTable<{
699
699
  readonly nowMillis: number;
700
700
  }, prepare: PrepareOAuthCommit<{
701
701
  readonly _tag: "Rejected";
702
+ } | {
703
+ readonly _tag: "Ambiguous";
702
704
  } | {
703
705
  readonly _tag: "Conflict";
704
706
  } | {
705
707
  readonly _tag: "Cancelled";
706
- } | {
707
- readonly _tag: "Ambiguous";
708
708
  } | {
709
709
  readonly _tag: "Linked";
710
710
  readonly credential: {
@@ -1070,6 +1070,8 @@ declare const makeOAuthAccountsServices: <S extends AnySQLiteTable<{
1070
1070
  readonly flow: OAuthConnectedPendingFlow;
1071
1071
  readonly authorization: OAuthConnectedActionAuthorization;
1072
1072
  }, prepare: PrepareOAuthCommit<{
1073
+ readonly _tag: "Rejected";
1074
+ } | {
1073
1075
  readonly _tag: "Issued";
1074
1076
  readonly flow: {
1075
1077
  readonly context: {
@@ -1161,8 +1163,6 @@ declare const makeOAuthAccountsServices: <S extends AnySQLiteTable<{
1161
1163
  };
1162
1164
  readonly retentionUntilMillis: number;
1163
1165
  };
1164
- } | {
1165
- readonly _tag: "Rejected";
1166
1166
  }, A>) => import("effect/Effect").Effect<PreparedCommit<A>, OAuthUnavailable, never>;
1167
1167
  readonly preflight: (input: OAuthConnectedAccess) => import("effect/Effect").Effect<OAuthConnectedPendingFlow | undefined, OAuthUnavailable>;
1168
1168
  readonly claim: <A>(input: {
@@ -1296,12 +1296,12 @@ declare const makeOAuthAccountsServices: <S extends AnySQLiteTable<{
1296
1296
  readonly nowMillis: number;
1297
1297
  }, prepare: PrepareOAuthCommit<{
1298
1298
  readonly _tag: "Rejected";
1299
+ } | {
1300
+ readonly _tag: "Ambiguous";
1299
1301
  } | {
1300
1302
  readonly _tag: "Conflict";
1301
1303
  } | {
1302
1304
  readonly _tag: "Cancelled";
1303
- } | {
1304
- readonly _tag: "Ambiguous";
1305
1305
  } | {
1306
1306
  readonly _tag: "Connected";
1307
1307
  readonly grant: {
package/dist/GitHub.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { OpenIdClientConfigurationError } from "./oauth/openid-client/models.mjs";
2
2
  import { GitHubOAuthAppConnectedProtocolOptions, GitHubOAuthAppGeneration, GitHubOAuthAppProtocolOptions } from "./oauth/github/models.mjs";
3
- import { gitHubOAuthAppConnectedProtocolLayer, gitHubOAuthAppProtocolLayer, makeGitHubOAuthAppConnectedProtocol, makeGitHubOAuthAppProtocol } from "./oauth/github/protocol.mjs";
3
+ import { gitHubOAuthAppConnectedProtocolLayer, gitHubOAuthAppProtocolLayer, gitHubOAuthAppProvider, makeGitHubOAuthAppConnectedProtocol, makeGitHubOAuthAppProtocol } from "./oauth/github/protocol.mjs";
4
4
  import { gitHubOAuthAppProviderKey } from "./oauth/github/identity.mjs";
5
- export { type GitHubOAuthAppConnectedProtocolOptions, type GitHubOAuthAppGeneration, type GitHubOAuthAppProtocolOptions, OpenIdClientConfigurationError, gitHubOAuthAppConnectedProtocolLayer, gitHubOAuthAppProtocolLayer, gitHubOAuthAppProviderKey, makeGitHubOAuthAppConnectedProtocol, makeGitHubOAuthAppProtocol };
5
+ export { type GitHubOAuthAppConnectedProtocolOptions, type GitHubOAuthAppGeneration, type GitHubOAuthAppProtocolOptions, OpenIdClientConfigurationError, gitHubOAuthAppConnectedProtocolLayer, gitHubOAuthAppProtocolLayer, gitHubOAuthAppProvider, gitHubOAuthAppProviderKey, makeGitHubOAuthAppConnectedProtocol, makeGitHubOAuthAppProtocol };
package/dist/GitHub.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  import { OpenIdClientConfigurationError } from "./oauth/openid-client/models.mjs";
2
2
  import { gitHubOAuthAppProviderKey } from "./oauth/github/identity.mjs";
3
- import { gitHubOAuthAppConnectedProtocolLayer, gitHubOAuthAppProtocolLayer, makeGitHubOAuthAppConnectedProtocol, makeGitHubOAuthAppProtocol } from "./oauth/github/protocol.mjs";
4
- export { OpenIdClientConfigurationError, gitHubOAuthAppConnectedProtocolLayer, gitHubOAuthAppProtocolLayer, gitHubOAuthAppProviderKey, makeGitHubOAuthAppConnectedProtocol, makeGitHubOAuthAppProtocol };
3
+ import { gitHubOAuthAppConnectedProtocolLayer, gitHubOAuthAppProtocolLayer, gitHubOAuthAppProvider, makeGitHubOAuthAppConnectedProtocol, makeGitHubOAuthAppProtocol } from "./oauth/github/protocol.mjs";
4
+ export { OpenIdClientConfigurationError, gitHubOAuthAppConnectedProtocolLayer, gitHubOAuthAppProtocolLayer, gitHubOAuthAppProvider, gitHubOAuthAppProviderKey, makeGitHubOAuthAppConnectedProtocol, makeGitHubOAuthAppProtocol };
@@ -1,4 +1,4 @@
1
- import { OpenIdClientAuthentication, OpenIdClientConfigurationError, PlainOAuthIdentity } from "./oauth/openid-client/models.mjs";
2
1
  import { OpenIdClientConnectedOAuthProvider, OpenIdClientConnectedOidcProvider, OpenIdClientConnectedProtocolOptions, OpenIdClientConnectedRefreshExpiry, OpenIdClientConnectedRevocation } from "./oauth/openid-client/connected/models.mjs";
2
+ import { OpenIdClientAuthentication, OpenIdClientConfigurationError, PlainOAuthIdentity } from "./oauth/openid-client/models.mjs";
3
3
  import { makeOpenIdClientConnectedProtocol, openIdClientConnectedProtocolLayer } from "./oauth/openid-client/connected/protocol.mjs";
4
4
  export { type OpenIdClientAuthentication, OpenIdClientConfigurationError, type OpenIdClientConnectedOAuthProvider, type OpenIdClientConnectedOidcProvider, type OpenIdClientConnectedProtocolOptions, type OpenIdClientConnectedRefreshExpiry, type OpenIdClientConnectedRevocation, type PlainOAuthIdentity, makeOpenIdClientConnectedProtocol, openIdClientConnectedProtocolLayer };
@@ -6,10 +6,14 @@ import { OAuthCallbackId, OAuthCodeResponse, OAuthProtocolConfiguration, OAuthPr
6
6
  import { OAuthConnectedConfiguration, OAuthConnectedGrantResponse, OAuthConnectedProfile, OAuthConnectedTokenContext, OAuthConnectedTokenMaterial } from "../connectedModels.mjs";
7
7
  import { OAuthConnectedProtocol } from "../OAuthConnectedProtocol.mjs";
8
8
  import { OAuthProtocol } from "../OAuthProtocol.mjs";
9
- import { OpenIdClientConfigurationError } from "../openid-client/models.mjs";
10
- import { GitHubOAuthAppConnectedProtocolOptions, GitHubOAuthAppProtocolOptions } from "./models.mjs";
9
+ import { OpenIdClientConfigurationError, OpenIdClientOAuthProvider } from "../openid-client/models.mjs";
10
+ import { GitHubOAuthAppConnectedProtocolOptions, GitHubOAuthAppGeneration, GitHubOAuthAppProtocolOptions } from "./models.mjs";
11
11
  import { Effect, Layer } from "effect";
12
12
  //#region src/oauth/github/protocol.d.ts
13
+ /** A GitHub.com OAuth App generation for the same provider list as generic OIDC.
14
+ * Retains GitHub receipt/error rules and requests read:user, with no repository access.
15
+ * Construction performs no I/O; invalid configuration throws the typed configuration error. */
16
+ declare const gitHubOAuthAppProvider: (registration: GitHubOAuthAppGeneration) => OpenIdClientOAuthProvider;
13
17
  declare const makeGitHubOAuthAppProtocol: (options: GitHubOAuthAppProtocolOptions) => Effect.Effect<{
14
18
  readonly prepareAuthorization: (input: {
15
19
  readonly provider: OAuthProviderKey;
@@ -50,5 +54,5 @@ declare const makeGitHubOAuthAppConnectedProtocol: (options: GitHubOAuthAppConne
50
54
  declare const gitHubOAuthAppProtocolLayer: (options: GitHubOAuthAppProtocolOptions) => Layer.Layer<OAuthProtocol, OAuthUnavailable | OpenIdClientConfigurationError, never>;
51
55
  declare const gitHubOAuthAppConnectedProtocolLayer: (options: GitHubOAuthAppConnectedProtocolOptions) => Layer.Layer<OAuthConnectedProtocol, OAuthUnavailable | OpenIdClientConfigurationError, never>;
52
56
  //#endregion
53
- export { gitHubOAuthAppConnectedProtocolLayer, gitHubOAuthAppProtocolLayer, makeGitHubOAuthAppConnectedProtocol, makeGitHubOAuthAppProtocol };
57
+ export { gitHubOAuthAppConnectedProtocolLayer, gitHubOAuthAppProtocolLayer, gitHubOAuthAppProvider, makeGitHubOAuthAppConnectedProtocol, makeGitHubOAuthAppProtocol };
54
58
  //# sourceMappingURL=protocol.d.mts.map
@@ -5,9 +5,9 @@ import { OAuthConnectedProfile } from "../connectedModels.mjs";
5
5
  import { OAuthConnectedProtocol } from "../OAuthConnectedProtocol.mjs";
6
6
  import { OAuthProtocol } from "../OAuthProtocol.mjs";
7
7
  import { OpenIdClientConfigurationError } from "../openid-client/models.mjs";
8
- import { DefiniteTokenRejection } from "../openid-client/compatibility.mjs";
8
+ import { DefiniteTokenRejection, tokenCompatibility } from "../openid-client/compatibility.mjs";
9
9
  import { boundedFetch } from "../openid-client/transport.mjs";
10
- import { makeOAuthProtocolWithCompatibility } from "../openid-client/protocol.mjs";
10
+ import { makeOpenIdClientOAuthProtocol } from "../openid-client/protocol.mjs";
11
11
  import { ProviderRevocation } from "../openid-client/ProviderRevocation.mjs";
12
12
  import { makeConnectedProtocolWithCompatibility } from "../openid-client/connected/protocol.mjs";
13
13
  import { decodeGitHubIdentity, gitHubOAuthAppProviderKey } from "./identity.mjs";
@@ -166,16 +166,29 @@ const revocationLayer = (options) => {
166
166
  });
167
167
  }) }));
168
168
  };
169
+ /** A GitHub.com OAuth App generation for the same provider list as generic OIDC.
170
+ * Retains GitHub receipt/error rules and requests read:user, with no repository access.
171
+ * Construction performs no I/O; invalid configuration throws the typed configuration error. */
172
+ const gitHubOAuthAppProvider = (registration) => {
173
+ let saved;
174
+ try {
175
+ saved = snapshotOAuthSync(generation, registration);
176
+ } catch {
177
+ throw invalid();
178
+ }
179
+ return {
180
+ ...provider(saved),
181
+ scopes: ["read:user"],
182
+ [tokenCompatibility]: compatibility
183
+ };
184
+ };
169
185
  const makeGitHubOAuthAppProtocol = Effect.fn("makeGitHubOAuthAppProtocol")(function* (options) {
170
186
  const saved = yield* capture(generations, options.registrations, options);
171
187
  if (saved.registrations.filter((item) => item.issuance === "active").length !== 1) return yield* invalid();
172
- return yield* makeOAuthProtocolWithCompatibility({
188
+ return yield* makeOpenIdClientOAuthProtocol({
173
189
  ...saved,
174
- providers: saved.registrations.map((item) => ({
175
- ...provider(item),
176
- scopes: ["read:user"]
177
- }))
178
- }, compatibility);
190
+ providers: saved.registrations.map(gitHubOAuthAppProvider)
191
+ });
179
192
  });
180
193
  const makeGitHubOAuthAppConnectedProtocol = Effect.fn("makeGitHubOAuthAppConnectedProtocol")(function* (options) {
181
194
  const saved = yield* capture(connectedGenerations, options.registrations, options);
@@ -199,6 +212,6 @@ const makeGitHubOAuthAppConnectedProtocol = Effect.fn("makeGitHubOAuthAppConnect
199
212
  const gitHubOAuthAppProtocolLayer = (options) => Layer.effect(OAuthProtocol, makeGitHubOAuthAppProtocol(options));
200
213
  const gitHubOAuthAppConnectedProtocolLayer = (options) => Layer.effect(OAuthConnectedProtocol, makeGitHubOAuthAppConnectedProtocol(options));
201
214
  //#endregion
202
- export { gitHubOAuthAppConnectedProtocolLayer, gitHubOAuthAppProtocolLayer, makeGitHubOAuthAppConnectedProtocol, makeGitHubOAuthAppProtocol };
215
+ export { gitHubOAuthAppConnectedProtocolLayer, gitHubOAuthAppProtocolLayer, gitHubOAuthAppProvider, makeGitHubOAuthAppConnectedProtocol, makeGitHubOAuthAppProtocol };
203
216
 
204
217
  //# sourceMappingURL=protocol.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.mjs","names":[],"sources":["../../../src/oauth/github/protocol.ts"],"sourcesContent":["import { Effect, Encoding, Layer, Predicate, Redacted, Schema } from \"effect\";\nimport type { CustomFetch } from \"openid-client\";\n\nimport { OAuthConnectedProfile } from \"../connectedModels\";\nimport { OAuthConnectedProtocol } from \"../OAuthConnectedProtocol\";\nimport { OAuthProtocol } from \"../OAuthProtocol\";\nimport {\n DefiniteTokenRejection,\n type ConnectedCompatibility,\n} from \"../openid-client/compatibility\";\nimport { makeConnectedProtocolWithCompatibility } from \"../openid-client/connected/protocol\";\nimport {\n OpenIdClientConfigurationError,\n type OpenIdClientOAuthProvider,\n} from \"../openid-client/models\";\nimport { makeOAuthProtocolWithCompatibility } from \"../openid-client/protocol\";\nimport { ProviderRevocation } from \"../openid-client/ProviderRevocation\";\nimport { boundedFetch } from \"../openid-client/transport\";\nimport { OAuthUnavailable } from \"../signInErrors\";\nimport { OAuthCallbackId, OAuthGeneration, OAuthIssuer, OAuthRedirectUri } from \"../signInModels\";\nimport { snapshotOAuthSync } from \"../signInSnapshot\";\nimport { decodeGitHubIdentity, gitHubOAuthAppProviderKey } from \"./identity\";\nimport type {\n GitHubOAuthAppConnectedProtocolOptions,\n GitHubOAuthAppGeneration,\n GitHubOAuthAppProtocolOptions,\n} from \"./models\";\n\nconst unavailable = () => OAuthUnavailable.make({});\nconst invalid = () => OpenIdClientConfigurationError.make({ reason: \"provider\" });\nconst issuer = OAuthIssuer.make(\"https://github.com\");\n\nconst headers = Object.freeze({\n Accept: \"application/vnd.github+json\",\n \"User-Agent\": \"effect-auth-github-oauth-app\",\n \"X-GitHub-Api-Version\": \"2026-03-10\",\n});\n\nconst generation = Schema.Struct({\n configurationGeneration: OAuthGeneration,\n issuance: Schema.Literals([\"active\", \"retired\"]),\n clientId: Schema.String.check(Schema.isPattern(/^[A-Za-z0-9._-]{1,256}$/)),\n clientSecret: Schema.RedactedFromValue(Schema.NonEmptyString.check(Schema.isMaxLength(4096))),\n callbacks: Schema.Array(\n Schema.Struct({ callbackId: OAuthCallbackId, redirectUri: OAuthRedirectUri }),\n ).check(Schema.isMinLength(1), Schema.isMaxLength(16)),\n});\n\nconst generations = Schema.Array(generation).check(Schema.isMinLength(1), Schema.isMaxLength(64));\n\nconst connectedGenerations = Schema.Array(\n Schema.Struct({\n ...generation.fields,\n profiles: Schema.Array(OAuthConnectedProfile).check(\n Schema.isMinLength(1),\n Schema.isMaxLength(64),\n ),\n }),\n).check(Schema.isMinLength(1), Schema.isMaxLength(64));\n\nconst timeout = Schema.Finite.check(Schema.isBetween({ minimum: 1, maximum: 30 }));\nconst isTimeout = Schema.is(timeout);\n\nconst capture = <S extends Schema.Codec<unknown, unknown, never, never>>(\n schema: S,\n registrations: S[\"Type\"],\n options: {\n readonly timeoutSeconds: number;\n readonly fetch?: GitHubOAuthAppProtocolOptions[\"fetch\"];\n },\n) =>\n Effect.try({\n try: () => {\n const result = snapshotOAuthSync(schema, registrations);\n const fetch = options.fetch;\n const timeoutSeconds = options.timeoutSeconds;\n\n if (!isTimeout(timeoutSeconds) || (fetch !== undefined && !Predicate.isFunction(fetch)))\n throw invalid();\n\n return { registrations: result, timeoutSeconds, ...(fetch === undefined ? {} : { fetch }) };\n },\n catch: invalid,\n });\n\nconst provider = (\n registration: GitHubOAuthAppGeneration,\n): Omit<OpenIdClientOAuthProvider, \"scopes\"> => ({\n provider: gitHubOAuthAppProviderKey,\n configurationGeneration: registration.configurationGeneration,\n issuance: registration.issuance,\n issuer,\n protocol: \"oauth\",\n responseIssuerMode: \"unsupported\",\n clientId: registration.clientId,\n authentication: { method: \"client_secret_post\", secret: registration.clientSecret },\n callbacks: registration.callbacks,\n authorizationEndpoint: \"https://github.com/login/oauth/authorize\",\n tokenEndpoint: \"https://github.com/login/oauth/access_token\",\n pkceS256: true,\n identitySource: {\n url: \"https://api.github.com/user\",\n headers,\n decodeIdentity: decodeGitHubIdentity,\n },\n});\n\nconst csvCell = Schema.String.check(Schema.isPattern(/^[A-Za-z0-9_:-]{1,256}$/));\nconst isCell = Schema.is(csvCell);\n\n/** GitHub's receipt is comma-delimited, unlike the generic OAuth scope string. */\nconst scopes = (\n receipt: string | undefined,\n expected: ReadonlyArray<string>,\n): ReadonlyArray<string> => {\n if (receipt === undefined || receipt.length > 16447) throw unavailable();\n\n const result =\n receipt === \"\" ? [] : receipt.split(\",\").map((cell) => cell.replace(/^[ \\t]+|[ \\t]+$/g, \"\"));\n\n if (\n result.length > 64 ||\n result.some((cell) => !isCell(cell)) ||\n new Set(result).size !== result.length ||\n result.length !== expected.length ||\n result.some((cell) => !expected.includes(cell))\n )\n throw unavailable();\n\n return result;\n};\n\nconst token = Schema.NonEmptyString.check(Schema.isMaxLength(16384));\nconst expiry = Schema.Finite.check(Schema.isGreaterThan(0));\n\nconst receiptSchema = Schema.Struct({\n access_token: token,\n token_type: Schema.String.check(Schema.isPattern(/^[Bb][Ee][Aa][Rr][Ee][Rr]$/)),\n scope: Schema.String.check(Schema.isMaxLength(16447)),\n expires_in: Schema.optionalKey(expiry),\n refresh_token: Schema.optionalKey(token),\n refresh_token_expires_in: Schema.optionalKey(expiry),\n});\n\n// oxlint-disable-next-line no-restricted-properties -- Inspect the bounded raw receipt before the maintained parser can coerce expiry fields.\nconst decodeReceipt = Schema.decodeUnknownSync(receiptSchema);\n\nconst encodeRevocation = Schema.encodeSync(\n Schema.fromJsonString(Schema.Struct({ access_token: token })),\n);\n\nconst terminalReceipt = Schema.Struct({\n error: Schema.NonEmptyString.check(Schema.isMaxLength(128)),\n error_description: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(4096))),\n error_uri: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(2048))),\n});\n\n// oxlint-disable-next-line no-restricted-properties -- Fully validate the raw terminal receipt before classifying a provider rejection.\nconst decodeTerminalReceipt = Schema.decodeUnknownSync(terminalReceipt);\n\nconst successKeys = [\n \"access_token\",\n \"token_type\",\n \"scope\",\n \"expires_in\",\n \"refresh_token\",\n \"refresh_token_expires_in\",\n \"id_token\",\n];\n\nconst compatibility: ConnectedCompatibility = Object.freeze<ConnectedCompatibility>({\n inspectReceipt: ({ body, status, contentType }, input) => {\n if (contentType?.split(\";\", 1)[0]?.trim().toLowerCase() !== \"application/json\")\n throw unavailable();\n if (!Predicate.isObject(body)) throw unavailable();\n if (Object.hasOwn(body, \"error\")) {\n if (successKeys.some((key) => Object.hasOwn(body, key))) throw unavailable();\n const terminal = decodeTerminalReceipt(body);\n\n if (\n (status === 200 || status === 400) &&\n terminal.error ===\n (input.operation === \"authorization_code\" ? \"bad_verification_code\" : \"bad_refresh_token\")\n ) {\n throw new DefiniteTokenRejection();\n }\n throw unavailable();\n }\n if (\n status !== 200 ||\n [\"error_description\", \"error_uri\", \"id_token\"].some((key) => Object.hasOwn(body, key))\n )\n throw unavailable();\n const receipt = decodeReceipt(body);\n\n scopes(receipt.scope, input.scopes);\n if (\n input.refreshRequired &&\n (receipt.refresh_token === undefined ||\n receipt.expires_in === undefined ||\n receipt.refresh_token_expires_in === undefined)\n )\n throw unavailable();\n },\n authorizationScopes: (permissions, refresh) =>\n refresh ? [...permissions, \"offline_access\"] : permissions,\n decodeScopes: scopes,\n includeRefreshScope: false,\n});\n\nconst revocationLayer = (\n options: Pick<GitHubOAuthAppConnectedProtocolOptions, \"fetch\" | \"timeoutSeconds\">,\n) => {\n const fetch: CustomFetch =\n options.fetch ??\n ((url, init) =>\n globalThis.fetch(url, {\n ...init,\n body: init.body instanceof Uint8Array ? new Uint8Array(init.body) : init.body,\n }));\n\n const timeoutSeconds = options.timeoutSeconds;\n\n return Layer.succeed(\n ProviderRevocation,\n ProviderRevocation.of({\n revoke: Effect.fn(\"GitHubOAuthApp.revoke\")(function* (input) {\n yield* Effect.tryPromise({\n try: async (effectSignal) => {\n if (\n input.authentication.method !== \"client_secret_post\" ||\n input.context.configuration.profile.clientRegistrationId !== input.clientId ||\n input.context.identity.provider !== gitHubOAuthAppProviderKey ||\n input.context.identity.issuer !== issuer\n )\n throw unavailable();\n const url = `https://api.github.com/applications/${encodeURIComponent(input.clientId)}/grant`;\n\n const signal = AbortSignal.any([\n effectSignal,\n AbortSignal.timeout(Math.ceil(timeoutSeconds * 1000)),\n ]);\n\n const transport = boundedFetch(fetch, signal, new Set([url]));\n\n const response = await transport(url, {\n method: \"DELETE\",\n redirect: \"manual\",\n headers: {\n ...headers,\n \"Content-Type\": \"application/json\",\n Authorization: `Basic ${Encoding.encodeBase64(`${input.clientId}:${Redacted.value(input.authentication.secret)}`)}`,\n },\n body: encodeRevocation({ access_token: Redacted.value(input.material.accessToken) }),\n signal,\n });\n\n signal.throwIfAborted();\n if (response.status !== 204) throw unavailable();\n },\n catch: unavailable,\n });\n }),\n }),\n );\n};\n\nexport const makeGitHubOAuthAppProtocol = Effect.fn(\"makeGitHubOAuthAppProtocol\")(function* (\n options: GitHubOAuthAppProtocolOptions,\n) {\n const saved = yield* capture(generations, options.registrations, options);\n\n if (saved.registrations.filter((item) => item.issuance === \"active\").length !== 1)\n return yield* invalid();\n\n return yield* makeOAuthProtocolWithCompatibility(\n {\n ...saved,\n providers: saved.registrations.map((item) => ({ ...provider(item), scopes: [\"read:user\"] })),\n },\n compatibility,\n );\n});\n\nexport const makeGitHubOAuthAppConnectedProtocol = Effect.fn(\"makeGitHubOAuthAppConnectedProtocol\")(\n function* (options: GitHubOAuthAppConnectedProtocolOptions) {\n const saved = yield* capture(connectedGenerations, options.registrations, options);\n\n if (saved.registrations.filter((item) => item.issuance === \"active\").length !== 1)\n return yield* invalid();\n for (const registration of saved.registrations) {\n for (const profile of registration.profiles) {\n if (\n profile.provider !== gitHubOAuthAppProviderKey ||\n profile.clientRegistrationId !== registration.clientId ||\n profile.resources.length !== 0 ||\n profile.scopes.some((scope) => scope === \"offline_access\" || !isCell(scope)) ||\n (profile.retention === \"access-only\"\n ? profile.refresh !== \"unsupported\" ||\n profile.maximumRefreshLifetimeMillis !== undefined\n : profile.refresh !== \"rotating\" || profile.maximumRefreshLifetimeMillis === undefined)\n )\n return yield* invalid();\n }\n }\n\n return yield* makeConnectedProtocolWithCompatibility(\n {\n ...saved,\n providers: saved.registrations.map((item) => ({\n ...provider(item),\n profiles: item.profiles,\n clientRegistrationId: item.clientId,\n resourceIndicators: \"unsupported\",\n refreshExpiry: { field: \"refresh_token_expires_in\", zero: \"expired\" },\n revocation: { mode: \"provider-cohort\" },\n })),\n },\n compatibility,\n ).pipe(Effect.provide(revocationLayer(saved)));\n },\n);\n\nexport const gitHubOAuthAppProtocolLayer = (options: GitHubOAuthAppProtocolOptions) =>\n Layer.effect(OAuthProtocol, makeGitHubOAuthAppProtocol(options));\n\nexport const gitHubOAuthAppConnectedProtocolLayer = (\n options: GitHubOAuthAppConnectedProtocolOptions,\n) => Layer.effect(OAuthConnectedProtocol, makeGitHubOAuthAppConnectedProtocol(options));\n"],"mappings":"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"}
1
+ {"version":3,"file":"protocol.mjs","names":[],"sources":["../../../src/oauth/github/protocol.ts"],"sourcesContent":["import { Effect, Encoding, Layer, Predicate, Redacted, Schema } from \"effect\";\nimport type { CustomFetch } from \"openid-client\";\n\nimport { OAuthConnectedProfile } from \"../connectedModels\";\nimport { OAuthConnectedProtocol } from \"../OAuthConnectedProtocol\";\nimport { OAuthProtocol } from \"../OAuthProtocol\";\nimport {\n DefiniteTokenRejection,\n tokenCompatibility,\n type ConnectedCompatibility,\n} from \"../openid-client/compatibility\";\nimport { makeConnectedProtocolWithCompatibility } from \"../openid-client/connected/protocol\";\nimport {\n OpenIdClientConfigurationError,\n type OpenIdClientOAuthProvider,\n} from \"../openid-client/models\";\nimport { makeOpenIdClientOAuthProtocol } from \"../openid-client/protocol\";\nimport { ProviderRevocation } from \"../openid-client/ProviderRevocation\";\nimport { boundedFetch } from \"../openid-client/transport\";\nimport { OAuthUnavailable } from \"../signInErrors\";\nimport { OAuthCallbackId, OAuthGeneration, OAuthIssuer, OAuthRedirectUri } from \"../signInModels\";\nimport { snapshotOAuthSync } from \"../signInSnapshot\";\nimport { decodeGitHubIdentity, gitHubOAuthAppProviderKey } from \"./identity\";\nimport type {\n GitHubOAuthAppConnectedProtocolOptions,\n GitHubOAuthAppGeneration,\n GitHubOAuthAppProtocolOptions,\n} from \"./models\";\n\nconst unavailable = () => OAuthUnavailable.make({});\nconst invalid = () => OpenIdClientConfigurationError.make({ reason: \"provider\" });\nconst issuer = OAuthIssuer.make(\"https://github.com\");\n\nconst headers = Object.freeze({\n Accept: \"application/vnd.github+json\",\n \"User-Agent\": \"effect-auth-github-oauth-app\",\n \"X-GitHub-Api-Version\": \"2026-03-10\",\n});\n\nconst generation = Schema.Struct({\n configurationGeneration: OAuthGeneration,\n issuance: Schema.Literals([\"active\", \"retired\"]),\n clientId: Schema.String.check(Schema.isPattern(/^[A-Za-z0-9._-]{1,256}$/)),\n clientSecret: Schema.RedactedFromValue(Schema.NonEmptyString.check(Schema.isMaxLength(4096))),\n callbacks: Schema.Array(\n Schema.Struct({ callbackId: OAuthCallbackId, redirectUri: OAuthRedirectUri }),\n ).check(Schema.isMinLength(1), Schema.isMaxLength(16)),\n});\n\nconst generations = Schema.Array(generation).check(Schema.isMinLength(1), Schema.isMaxLength(64));\n\nconst connectedGenerations = Schema.Array(\n Schema.Struct({\n ...generation.fields,\n profiles: Schema.Array(OAuthConnectedProfile).check(\n Schema.isMinLength(1),\n Schema.isMaxLength(64),\n ),\n }),\n).check(Schema.isMinLength(1), Schema.isMaxLength(64));\n\nconst timeout = Schema.Finite.check(Schema.isBetween({ minimum: 1, maximum: 30 }));\nconst isTimeout = Schema.is(timeout);\n\nconst capture = <S extends Schema.Codec<unknown, unknown, never, never>>(\n schema: S,\n registrations: S[\"Type\"],\n options: {\n readonly timeoutSeconds: number;\n readonly fetch?: GitHubOAuthAppProtocolOptions[\"fetch\"];\n },\n) =>\n Effect.try({\n try: () => {\n const result = snapshotOAuthSync(schema, registrations);\n const fetch = options.fetch;\n const timeoutSeconds = options.timeoutSeconds;\n\n if (!isTimeout(timeoutSeconds) || (fetch !== undefined && !Predicate.isFunction(fetch)))\n throw invalid();\n\n return { registrations: result, timeoutSeconds, ...(fetch === undefined ? {} : { fetch }) };\n },\n catch: invalid,\n });\n\nconst provider = (\n registration: GitHubOAuthAppGeneration,\n): Omit<OpenIdClientOAuthProvider, \"scopes\"> => ({\n provider: gitHubOAuthAppProviderKey,\n configurationGeneration: registration.configurationGeneration,\n issuance: registration.issuance,\n issuer,\n protocol: \"oauth\",\n responseIssuerMode: \"unsupported\",\n clientId: registration.clientId,\n authentication: { method: \"client_secret_post\", secret: registration.clientSecret },\n callbacks: registration.callbacks,\n authorizationEndpoint: \"https://github.com/login/oauth/authorize\",\n tokenEndpoint: \"https://github.com/login/oauth/access_token\",\n pkceS256: true,\n identitySource: {\n url: \"https://api.github.com/user\",\n headers,\n decodeIdentity: decodeGitHubIdentity,\n },\n});\n\nconst csvCell = Schema.String.check(Schema.isPattern(/^[A-Za-z0-9_:-]{1,256}$/));\nconst isCell = Schema.is(csvCell);\n\n/** GitHub's receipt is comma-delimited, unlike the generic OAuth scope string. */\nconst scopes = (\n receipt: string | undefined,\n expected: ReadonlyArray<string>,\n): ReadonlyArray<string> => {\n if (receipt === undefined || receipt.length > 16447) throw unavailable();\n\n const result =\n receipt === \"\" ? [] : receipt.split(\",\").map((cell) => cell.replace(/^[ \\t]+|[ \\t]+$/g, \"\"));\n\n if (\n result.length > 64 ||\n result.some((cell) => !isCell(cell)) ||\n new Set(result).size !== result.length ||\n result.length !== expected.length ||\n result.some((cell) => !expected.includes(cell))\n )\n throw unavailable();\n\n return result;\n};\n\nconst token = Schema.NonEmptyString.check(Schema.isMaxLength(16384));\nconst expiry = Schema.Finite.check(Schema.isGreaterThan(0));\n\nconst receiptSchema = Schema.Struct({\n access_token: token,\n token_type: Schema.String.check(Schema.isPattern(/^[Bb][Ee][Aa][Rr][Ee][Rr]$/)),\n scope: Schema.String.check(Schema.isMaxLength(16447)),\n expires_in: Schema.optionalKey(expiry),\n refresh_token: Schema.optionalKey(token),\n refresh_token_expires_in: Schema.optionalKey(expiry),\n});\n\n// oxlint-disable-next-line no-restricted-properties -- Inspect the bounded raw receipt before the maintained parser can coerce expiry fields.\nconst decodeReceipt = Schema.decodeUnknownSync(receiptSchema);\n\nconst encodeRevocation = Schema.encodeSync(\n Schema.fromJsonString(Schema.Struct({ access_token: token })),\n);\n\nconst terminalReceipt = Schema.Struct({\n error: Schema.NonEmptyString.check(Schema.isMaxLength(128)),\n error_description: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(4096))),\n error_uri: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(2048))),\n});\n\n// oxlint-disable-next-line no-restricted-properties -- Fully validate the raw terminal receipt before classifying a provider rejection.\nconst decodeTerminalReceipt = Schema.decodeUnknownSync(terminalReceipt);\n\nconst successKeys = [\n \"access_token\",\n \"token_type\",\n \"scope\",\n \"expires_in\",\n \"refresh_token\",\n \"refresh_token_expires_in\",\n \"id_token\",\n];\n\nconst compatibility: ConnectedCompatibility = Object.freeze<ConnectedCompatibility>({\n inspectReceipt: ({ body, status, contentType }, input) => {\n if (contentType?.split(\";\", 1)[0]?.trim().toLowerCase() !== \"application/json\")\n throw unavailable();\n if (!Predicate.isObject(body)) throw unavailable();\n if (Object.hasOwn(body, \"error\")) {\n if (successKeys.some((key) => Object.hasOwn(body, key))) throw unavailable();\n const terminal = decodeTerminalReceipt(body);\n\n if (\n (status === 200 || status === 400) &&\n terminal.error ===\n (input.operation === \"authorization_code\" ? \"bad_verification_code\" : \"bad_refresh_token\")\n ) {\n throw new DefiniteTokenRejection();\n }\n throw unavailable();\n }\n if (\n status !== 200 ||\n [\"error_description\", \"error_uri\", \"id_token\"].some((key) => Object.hasOwn(body, key))\n )\n throw unavailable();\n const receipt = decodeReceipt(body);\n\n scopes(receipt.scope, input.scopes);\n if (\n input.refreshRequired &&\n (receipt.refresh_token === undefined ||\n receipt.expires_in === undefined ||\n receipt.refresh_token_expires_in === undefined)\n )\n throw unavailable();\n },\n authorizationScopes: (permissions, refresh) =>\n refresh ? [...permissions, \"offline_access\"] : permissions,\n decodeScopes: scopes,\n includeRefreshScope: false,\n});\n\nconst revocationLayer = (\n options: Pick<GitHubOAuthAppConnectedProtocolOptions, \"fetch\" | \"timeoutSeconds\">,\n) => {\n const fetch: CustomFetch =\n options.fetch ??\n ((url, init) =>\n globalThis.fetch(url, {\n ...init,\n body: init.body instanceof Uint8Array ? new Uint8Array(init.body) : init.body,\n }));\n\n const timeoutSeconds = options.timeoutSeconds;\n\n return Layer.succeed(\n ProviderRevocation,\n ProviderRevocation.of({\n revoke: Effect.fn(\"GitHubOAuthApp.revoke\")(function* (input) {\n yield* Effect.tryPromise({\n try: async (effectSignal) => {\n if (\n input.authentication.method !== \"client_secret_post\" ||\n input.context.configuration.profile.clientRegistrationId !== input.clientId ||\n input.context.identity.provider !== gitHubOAuthAppProviderKey ||\n input.context.identity.issuer !== issuer\n )\n throw unavailable();\n const url = `https://api.github.com/applications/${encodeURIComponent(input.clientId)}/grant`;\n\n const signal = AbortSignal.any([\n effectSignal,\n AbortSignal.timeout(Math.ceil(timeoutSeconds * 1000)),\n ]);\n\n const transport = boundedFetch(fetch, signal, new Set([url]));\n\n const response = await transport(url, {\n method: \"DELETE\",\n redirect: \"manual\",\n headers: {\n ...headers,\n \"Content-Type\": \"application/json\",\n Authorization: `Basic ${Encoding.encodeBase64(`${input.clientId}:${Redacted.value(input.authentication.secret)}`)}`,\n },\n body: encodeRevocation({ access_token: Redacted.value(input.material.accessToken) }),\n signal,\n });\n\n signal.throwIfAborted();\n if (response.status !== 204) throw unavailable();\n },\n catch: unavailable,\n });\n }),\n }),\n );\n};\n\n/** A GitHub.com OAuth App generation for the same provider list as generic OIDC.\n * Retains GitHub receipt/error rules and requests read:user, with no repository access.\n * Construction performs no I/O; invalid configuration throws the typed configuration error. */\nexport const gitHubOAuthAppProvider = (\n registration: GitHubOAuthAppGeneration,\n): OpenIdClientOAuthProvider => {\n let saved: GitHubOAuthAppGeneration;\n\n try {\n saved = snapshotOAuthSync(generation, registration);\n } catch {\n throw invalid();\n }\n\n return {\n ...provider(saved),\n scopes: [\"read:user\"],\n [tokenCompatibility]: compatibility,\n };\n};\n\nexport const makeGitHubOAuthAppProtocol = Effect.fn(\"makeGitHubOAuthAppProtocol\")(function* (\n options: GitHubOAuthAppProtocolOptions,\n) {\n const saved = yield* capture(generations, options.registrations, options);\n\n if (saved.registrations.filter((item) => item.issuance === \"active\").length !== 1)\n return yield* invalid();\n\n return yield* makeOpenIdClientOAuthProtocol({\n ...saved,\n providers: saved.registrations.map(gitHubOAuthAppProvider),\n });\n});\n\nexport const makeGitHubOAuthAppConnectedProtocol = Effect.fn(\"makeGitHubOAuthAppConnectedProtocol\")(\n function* (options: GitHubOAuthAppConnectedProtocolOptions) {\n const saved = yield* capture(connectedGenerations, options.registrations, options);\n\n if (saved.registrations.filter((item) => item.issuance === \"active\").length !== 1)\n return yield* invalid();\n for (const registration of saved.registrations) {\n for (const profile of registration.profiles) {\n if (\n profile.provider !== gitHubOAuthAppProviderKey ||\n profile.clientRegistrationId !== registration.clientId ||\n profile.resources.length !== 0 ||\n profile.scopes.some((scope) => scope === \"offline_access\" || !isCell(scope)) ||\n (profile.retention === \"access-only\"\n ? profile.refresh !== \"unsupported\" ||\n profile.maximumRefreshLifetimeMillis !== undefined\n : profile.refresh !== \"rotating\" || profile.maximumRefreshLifetimeMillis === undefined)\n )\n return yield* invalid();\n }\n }\n\n return yield* makeConnectedProtocolWithCompatibility(\n {\n ...saved,\n providers: saved.registrations.map((item) => ({\n ...provider(item),\n profiles: item.profiles,\n clientRegistrationId: item.clientId,\n resourceIndicators: \"unsupported\",\n refreshExpiry: { field: \"refresh_token_expires_in\", zero: \"expired\" },\n revocation: { mode: \"provider-cohort\" },\n })),\n },\n compatibility,\n ).pipe(Effect.provide(revocationLayer(saved)));\n },\n);\n\nexport const gitHubOAuthAppProtocolLayer = (options: GitHubOAuthAppProtocolOptions) =>\n Layer.effect(OAuthProtocol, makeGitHubOAuthAppProtocol(options));\n\nexport const gitHubOAuthAppConnectedProtocolLayer = (\n options: GitHubOAuthAppConnectedProtocolOptions,\n) => Layer.effect(OAuthConnectedProtocol, makeGitHubOAuthAppConnectedProtocol(options));\n"],"mappings":"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"}
@@ -1 +1,22 @@
1
- import "./connected/models.mjs";
1
+ import "./connected/models.mjs";
2
+ import { Schema } from "effect";
3
+ //#region src/oauth/openid-client/compatibility.d.ts
4
+ /** Pure private provider rules, never part of the generic public options. */
5
+ interface TokenCompatibility {
6
+ readonly inspectReceipt: (receipt: {
7
+ readonly body: unknown;
8
+ readonly status: number;
9
+ readonly contentType: string | null;
10
+ }, input: {
11
+ readonly scopes: ReadonlyArray<string>;
12
+ readonly refreshRequired: boolean;
13
+ readonly operation: "authorization_code" | "refresh_token";
14
+ }) => void;
15
+ }
16
+ /** First-party rules travel with the exact provider generation. The symbol stays
17
+ * private so generic provider options do not expose grant-bearing hooks. */
18
+ declare const tokenCompatibility: unique symbol;
19
+ declare const TokenCompatibility: Schema.declare<TokenCompatibility, TokenCompatibility>;
20
+ //#endregion
21
+ export { TokenCompatibility, tokenCompatibility };
22
+ //# sourceMappingURL=compatibility.d.mts.map
@@ -1,6 +1,11 @@
1
+ import { Predicate, Schema } from "effect";
1
2
  //#region src/oauth/openid-client/compatibility.ts
3
+ /** First-party rules travel with the exact provider generation. The symbol stays
4
+ * private so generic provider options do not expose grant-bearing hooks. */
5
+ const tokenCompatibility = Symbol("effect-auth/OpenIdClient/tokenCompatibility");
6
+ const TokenCompatibility = Schema.declare((input) => Predicate.isObject(input) && "inspectReceipt" in input && Predicate.isFunction(input.inspectReceipt));
2
7
  var DefiniteTokenRejection = class extends Error {};
3
8
  //#endregion
4
- export { DefiniteTokenRejection };
9
+ export { DefiniteTokenRejection, TokenCompatibility, tokenCompatibility };
5
10
 
6
11
  //# sourceMappingURL=compatibility.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"compatibility.mjs","names":[],"sources":["../../../src/oauth/openid-client/compatibility.ts"],"sourcesContent":["import type {\n OpenIdClientConnectedOAuthProvider,\n OpenIdClientConnectedProtocolOptions,\n} from \"./connected/models\";\n\n/** Pure private provider rules, never part of the generic public options. */\nexport interface TokenCompatibility {\n readonly inspectReceipt: (\n receipt: {\n readonly body: unknown;\n readonly status: number;\n readonly contentType: string | null;\n },\n input: {\n readonly scopes: ReadonlyArray<string>;\n readonly refreshRequired: boolean;\n readonly operation: \"authorization_code\" | \"refresh_token\";\n },\n ) => void;\n}\n\nexport class DefiniteTokenRejection extends Error {}\n\nexport interface ConnectedCompatibility extends TokenCompatibility {\n readonly authorizationScopes: (\n scopes: ReadonlyArray<string>,\n refresh: boolean,\n ) => ReadonlyArray<string>;\n readonly decodeScopes: (\n receipt: string | undefined,\n expected: ReadonlyArray<string>,\n ) => ReadonlyArray<string>;\n readonly includeRefreshScope: boolean;\n}\n\nexport type ProviderConnectedOAuth<R> = Omit<\n OpenIdClientConnectedOAuthProvider<R>,\n \"revocation\"\n> & {\n readonly revocation: { readonly mode: \"provider-cohort\" };\n};\n\nexport type ConnectedOptions<R> = Omit<OpenIdClientConnectedProtocolOptions<R>, \"providers\"> & {\n readonly providers: ReadonlyArray<\n OpenIdClientConnectedProtocolOptions<R>[\"providers\"][number] | ProviderConnectedOAuth<R>\n >;\n};\n"],"mappings":";AAqBA,IAAa,yBAAb,cAA4C,MAAM,CAAC"}
1
+ {"version":3,"file":"compatibility.mjs","names":[],"sources":["../../../src/oauth/openid-client/compatibility.ts"],"sourcesContent":["import { Predicate, Schema } from \"effect\";\n\nimport type {\n OpenIdClientConnectedOAuthProvider,\n OpenIdClientConnectedProtocolOptions,\n} from \"./connected/models\";\n\n/** Pure private provider rules, never part of the generic public options. */\nexport interface TokenCompatibility {\n readonly inspectReceipt: (\n receipt: {\n readonly body: unknown;\n readonly status: number;\n readonly contentType: string | null;\n },\n input: {\n readonly scopes: ReadonlyArray<string>;\n readonly refreshRequired: boolean;\n readonly operation: \"authorization_code\" | \"refresh_token\";\n },\n ) => void;\n}\n\n/** First-party rules travel with the exact provider generation. The symbol stays\n * private so generic provider options do not expose grant-bearing hooks. */\nexport const tokenCompatibility = Symbol(\"effect-auth/OpenIdClient/tokenCompatibility\");\n\nexport const TokenCompatibility = Schema.declare<TokenCompatibility>(\n (input): input is TokenCompatibility =>\n Predicate.isObject(input) &&\n \"inspectReceipt\" in input &&\n Predicate.isFunction(input.inspectReceipt),\n);\n\nexport class DefiniteTokenRejection extends Error {}\n\nexport interface ConnectedCompatibility extends TokenCompatibility {\n readonly authorizationScopes: (\n scopes: ReadonlyArray<string>,\n refresh: boolean,\n ) => ReadonlyArray<string>;\n readonly decodeScopes: (\n receipt: string | undefined,\n expected: ReadonlyArray<string>,\n ) => ReadonlyArray<string>;\n readonly includeRefreshScope: boolean;\n}\n\nexport type ProviderConnectedOAuth<R> = Omit<\n OpenIdClientConnectedOAuthProvider<R>,\n \"revocation\"\n> & {\n readonly revocation: { readonly mode: \"provider-cohort\" };\n};\n\nexport type ConnectedOptions<R> = Omit<OpenIdClientConnectedProtocolOptions<R>, \"providers\"> & {\n readonly providers: ReadonlyArray<\n OpenIdClientConnectedProtocolOptions<R>[\"providers\"][number] | ProviderConnectedOAuth<R>\n >;\n};\n"],"mappings":";;;;AAyBA,MAAa,qBAAqB,OAAO,6CAA6C;AAEtF,MAAa,qBAAqB,OAAO,SACtC,UACC,UAAU,SAAS,KAAK,KACxB,oBAAoB,SACpB,UAAU,WAAW,MAAM,cAAc,CAC7C;AAEA,IAAa,yBAAb,cAA4C,MAAM,CAAC"}
@@ -3,6 +3,7 @@ import { OAuthAuthorizationUrl, OAuthCallbackId, OAuthGeneration, OAuthIssuer, O
3
3
  import { OAuthUnavailable } from "../signInErrors.mjs";
4
4
  import { freezeOAuth } from "../signInSnapshot.mjs";
5
5
  import { OpenIdClientConfigurationError } from "./models.mjs";
6
+ import { TokenCompatibility, tokenCompatibility } from "./compatibility.mjs";
6
7
  import { boundedFetch } from "./transport.mjs";
7
8
  import { Effect, Predicate, Redacted, Schema } from "effect";
8
9
  import * as client from "openid-client";
@@ -52,6 +53,7 @@ const optionsSchema = () => Schema.toType(Schema.Struct({
52
53
  }), Schema.Struct({
53
54
  ...common,
54
55
  protocol: Schema.Literal("oauth"),
56
+ [tokenCompatibility]: Schema.optionalKey(TokenCompatibility),
55
57
  authorizationEndpoint: boundedString(2048),
56
58
  tokenEndpoint: boundedString(2048),
57
59
  pkceS256: Schema.Literal(true),
@@ -1 +1 @@
1
- {"version":3,"file":"configuration.mjs","names":[],"sources":["../../../src/oauth/openid-client/configuration.ts"],"sourcesContent":["import { Effect, Predicate, Redacted, Schema } from \"effect\";\nimport * as client from \"openid-client\";\n\nimport { OAuthProviderKey } from \"../schema\";\nimport { OAuthUnavailable } from \"../signInErrors\";\nimport {\n OAuthAuthorizationUrl,\n OAuthCallbackId,\n OAuthGeneration,\n OAuthIssuer,\n OAuthRedirectUri,\n} from \"../signInModels\";\nimport { freezeOAuth } from \"../signInSnapshot\";\nimport {\n OpenIdClientConfigurationError,\n type OpenIdClientAuthentication,\n type OpenIdClientOAuthProvider,\n type OpenIdClientOAuthProtocolOptions,\n type OpenIdClientOidcProvider,\n} from \"./models\";\nimport { boundedFetch } from \"./transport\";\n\nconst boundedString = (maximum: number) =>\n Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(maximum));\n\nconst fields = Schema.Record(\n Schema.String.check(Schema.isPattern(/^[A-Za-z][A-Za-z0-9._~-]{0,63}$/)),\n Schema.String.check(Schema.isMaxLength(2048)),\n).check(Schema.makeFilter((record) => Object.keys(record).length <= 16));\n\nconst secret = Schema.RedactedFromValue(boundedString(4096));\n\nconst authentication = Schema.Union([\n Schema.Struct({ method: Schema.Literal(\"client_secret_basic\"), secret }),\n Schema.Struct({ method: Schema.Literal(\"client_secret_post\"), secret }),\n Schema.Struct({ method: Schema.Literal(\"none\"), publicClient: Schema.Literal(true) }),\n]);\n\nconst common = {\n provider: OAuthProviderKey,\n configurationGeneration: OAuthGeneration,\n issuance: Schema.Literals([\"active\", \"retired\"]),\n issuer: OAuthIssuer,\n responseIssuerMode: Schema.Literals([\"required\", \"unsupported\"]),\n clientId: boundedString(1024),\n authentication,\n callbacks: Schema.Array(\n Schema.Struct({ callbackId: OAuthCallbackId, redirectUri: OAuthRedirectUri }),\n ).check(Schema.isMinLength(1), Schema.isMaxLength(16)),\n scopes: Schema.Array(\n Schema.String.check(Schema.isPattern(/^[\\x21\\x23-\\x5b\\x5d-\\x7e]{1,128}$/)),\n ).check(Schema.isMaxLength(32)),\n authorizationParameters: Schema.optionalKey(fields),\n tokenParameters: Schema.optionalKey(fields),\n};\n\nconst optionsSchema = <R>() =>\n Schema.toType(\n Schema.Struct({\n providers: Schema.Array(\n Schema.Union([\n Schema.Struct({\n ...common,\n protocol: Schema.Literal(\"oidc\"),\n idTokenSignedResponseAlg: Schema.Literal(\"RS256\"),\n maxAgeSeconds: Schema.optionalKey(\n Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 86400 })),\n ),\n }),\n Schema.Struct({\n ...common,\n protocol: Schema.Literal(\"oauth\"),\n authorizationEndpoint: boundedString(2048),\n tokenEndpoint: boundedString(2048),\n pkceS256: Schema.Literal(true),\n identitySource: Schema.Struct({\n url: boundedString(2048),\n headers: Schema.optionalKey(fields),\n // A configured function is trusted application code; its result has a separate schema boundary.\n decodeIdentity: Schema.declare<\n OpenIdClientOAuthProvider<R>[\"identitySource\"][\"decodeIdentity\"]\n >(\n (\n input,\n ): input is OpenIdClientOAuthProvider<R>[\"identitySource\"][\"decodeIdentity\"] =>\n Predicate.isFunction(input),\n ),\n }),\n }),\n ]),\n ).check(Schema.isMinLength(1), Schema.isMaxLength(64)),\n timeoutSeconds: Schema.Finite.check(Schema.isBetween({ minimum: 1, maximum: 30 })),\n fetch: Schema.optionalKey(\n Schema.declare<client.CustomFetch>((input): input is client.CustomFetch =>\n Predicate.isFunction(input),\n ),\n ),\n }),\n );\n\nconst reserved = new Set([\n \"client_id\",\n \"client_secret\",\n \"client_assertion\",\n \"client_assertion_type\",\n \"redirect_uri\",\n \"response_type\",\n \"response_mode\",\n \"state\",\n \"code\",\n \"code_verifier\",\n \"code_challenge\",\n \"code_challenge_method\",\n \"nonce\",\n \"scope\",\n \"iss\",\n \"grant_type\",\n \"max_age\",\n \"request\",\n \"request_uri\",\n \"authorization_details\",\n \"id_token_hint\",\n \"login_hint\",\n \"login_hint_token\",\n \"subject_token\",\n \"subject_token_type\",\n \"actor_token\",\n \"actor_token_type\",\n \"requested_token_type\",\n]);\n\nconst forbiddenHeaders = new Set([\n \"authorization\",\n \"proxy-authorization\",\n \"cookie\",\n \"host\",\n \"content-length\",\n \"content-type\",\n \"transfer-encoding\",\n \"connection\",\n \"upgrade\",\n \"trailer\",\n \"te\",\n]);\n\nconst configError = (reason: OpenIdClientConfigurationError[\"reason\"]) =>\n OpenIdClientConfigurationError.make({ reason });\n\nexport const endpoint = (value: string): URL => {\n const url = new URL(value);\n\n if (\n url.protocol !== \"https:\" ||\n url.username !== \"\" ||\n url.password !== \"\" ||\n value.includes(\"#\") ||\n // oxlint-disable-next-line no-control-regex -- Reject ambiguous protocol URL control characters.\n /[\\s\\\\\\u0000-\\u001f\\u007f]/u.test(value)\n )\n throw configError(\"metadata\");\n\n return url;\n};\n\nconst checkParameters = (parameters: Readonly<Record<string, string>> | undefined) => {\n for (const key of Object.keys(parameters ?? {})) {\n if (reserved.has(key.toLowerCase())) throw configError(\"parameters\");\n }\n};\n\nexport const clientAuthentication = (\n authentication: OpenIdClientAuthentication,\n): client.ClientAuth => {\n switch (authentication.method) {\n case \"client_secret_basic\":\n return client.ClientSecretBasic(Redacted.value(authentication.secret));\n case \"client_secret_post\":\n return client.ClientSecretPost(Redacted.value(authentication.secret));\n case \"none\":\n return client.None();\n }\n};\n\nexport type Provider<R> = OpenIdClientOidcProvider | OpenIdClientOAuthProvider<R>;\n\nexport interface InstalledProvider<R> {\n readonly provider: Provider<R>;\n readonly metadata: client.ServerMetadata;\n readonly allowedUrls: ReadonlySet<string>;\n}\n\nexport const makeAuthorizationParameters = (\n configuration: {\n readonly protocol: \"oauth\" | \"oidc\";\n readonly authorizationParameters?: Readonly<Record<string, string>>;\n readonly scopes: ReadonlyArray<string>;\n readonly maxAgeSeconds?: number;\n },\n redirectUri: string,\n generated: { readonly state: string; readonly challenge: string; readonly nonce?: string },\n): Record<string, string> => ({\n ...configuration.authorizationParameters,\n response_type: \"code\",\n response_mode: \"query\",\n redirect_uri: redirectUri,\n scope: configuration.scopes.join(\" \"),\n state: generated.state,\n code_challenge: generated.challenge,\n code_challenge_method: \"S256\",\n ...(generated.nonce === undefined ? {} : { nonce: generated.nonce }),\n ...(configuration.protocol === \"oidc\" && configuration.maxAgeSeconds !== undefined\n ? { max_age: String(configuration.maxAgeSeconds) }\n : {}),\n});\n\nconst metadataSchema = Schema.Struct({\n issuer: OAuthIssuer,\n authorization_endpoint: boundedString(2048),\n token_endpoint: boundedString(2048),\n jwks_uri: Schema.optionalKey(boundedString(2048)),\n code_challenge_methods_supported: Schema.optionalKey(Schema.Array(boundedString(64))),\n response_types_supported: Schema.optionalKey(Schema.Array(boundedString(64))),\n id_token_signing_alg_values_supported: Schema.optionalKey(Schema.Array(boundedString(64))),\n token_endpoint_auth_methods_supported: Schema.optionalKey(Schema.Array(boundedString(64))),\n authorization_response_iss_parameter_supported: Schema.optionalKey(Schema.Boolean),\n});\n\nexport const installConfigurations = Effect.fn(\"OpenIdClient.installConfigurations\")(function* <R>(\n input: OpenIdClientOAuthProtocolOptions<R>,\n) {\n const options = yield* Schema.decodeEffect(optionsSchema<R>())(input).pipe(\n Effect.mapError(() => configError(\"provider\")),\n );\n\n // Detach secrets as well as arrays and records before retaining configuration.\n const providers = options.providers.map((provider): Provider<R> => {\n const detached = {\n callbacks: provider.callbacks.map((callback) => ({ ...callback })),\n scopes: [...provider.scopes],\n ...(provider.authorizationParameters === undefined\n ? {}\n : { authorizationParameters: { ...provider.authorizationParameters } }),\n ...(provider.tokenParameters === undefined\n ? {}\n : { tokenParameters: { ...provider.tokenParameters } }),\n authentication:\n provider.authentication.method === \"none\"\n ? { ...provider.authentication }\n : {\n ...provider.authentication,\n secret: Redacted.make(Redacted.value(provider.authentication.secret)),\n },\n };\n\n return provider.protocol === \"oidc\"\n ? { ...provider, ...detached }\n : {\n ...provider,\n ...detached,\n identitySource: {\n ...provider.identitySource,\n ...(provider.identitySource.headers === undefined\n ? {}\n : { headers: { ...provider.identitySource.headers } }),\n },\n };\n });\n\n const fetch: client.CustomFetch =\n options.fetch ??\n ((url, init) =>\n globalThis.fetch(url, {\n ...init,\n body: init.body instanceof Uint8Array ? new Uint8Array(init.body) : init.body,\n }));\n\n yield* Effect.try({\n try: () => {\n const generations = new Set<string>();\n const active = new Set<string>();\n const names = new Set<string>();\n\n for (const provider of providers) {\n const generation = `${provider.provider.length}:${provider.provider}:${provider.configurationGeneration}`;\n\n if (generations.has(generation)) throw configError(\"generation\");\n generations.add(generation);\n names.add(provider.provider);\n if (provider.issuance === \"active\") {\n if (active.has(provider.provider)) throw configError(\"generation\");\n active.add(provider.provider);\n }\n const issuer = endpoint(provider.issuer);\n\n if (provider.issuer.includes(\"?\") || issuer.pathname.includes(\"/.well-known/\"))\n throw configError(\"issuer\");\n if (new Set(provider.scopes).size !== provider.scopes.length)\n throw configError(\"parameters\");\n if ((provider.protocol === \"oidc\") !== provider.scopes.includes(\"openid\"))\n throw configError(\"parameters\");\n checkParameters(provider.authorizationParameters);\n checkParameters(provider.tokenParameters);\n const callbacks = new Set<string>();\n\n for (const callback of provider.callbacks) {\n const url = endpoint(callback.redirectUri);\n\n if (\n url.href !== callback.redirectUri ||\n callback.redirectUri.includes(\"?\") ||\n callbacks.has(callback.callbackId)\n )\n throw configError(\"callback\");\n callbacks.add(callback.callbackId);\n for (const other of providers) {\n if (provider.issuer === other.issuer) continue;\n if (\n provider.responseIssuerMode === \"required\" &&\n other.responseIssuerMode === \"required\"\n )\n continue;\n if (other.callbacks.some((candidate) => candidate.redirectUri === callback.redirectUri))\n throw configError(\"callback\");\n }\n }\n if (provider.protocol === \"oauth\") {\n endpoint(provider.identitySource.url);\n for (const key of Object.keys(provider.identitySource.headers ?? {})) {\n if (forbiddenHeaders.has(key.toLowerCase())) throw configError(\"identity-source\");\n }\n new Headers(provider.identitySource.headers);\n }\n freezeOAuth(provider);\n }\n if (active.size !== names.size) throw configError(\"generation\");\n },\n catch: (error) =>\n Schema.is(OpenIdClientConfigurationError)(error) ? error : configError(\"provider\"),\n });\n const installed: InstalledProvider<R>[] = [];\n\n for (const provider of providers) {\n let raw: client.ServerMetadata;\n\n if (provider.protocol === \"oidc\") {\n const discoveryUrl = new URL(provider.issuer);\n\n discoveryUrl.pathname = `${discoveryUrl.pathname.replace(/\\/$/u, \"\")}/.well-known/openid-configuration`;\n\n const configuration = yield* Effect.tryPromise({\n try: (signal) =>\n client.discovery(\n new URL(provider.issuer),\n provider.clientId,\n {\n id_token_signed_response_alg: provider.idTokenSignedResponseAlg,\n [client.clockSkew]: 0,\n [client.clockTolerance]: 0,\n },\n clientAuthentication(provider.authentication),\n {\n timeout: options.timeoutSeconds,\n execute: [client.enableNonRepudiationChecks],\n [client.customFetch]: boundedFetch(fetch, signal, new Set([discoveryUrl.href])),\n },\n ),\n catch: () => OAuthUnavailable.make({}),\n });\n\n raw = configuration.serverMetadata();\n } else {\n raw = {\n issuer: provider.issuer,\n authorization_endpoint: provider.authorizationEndpoint,\n token_endpoint: provider.tokenEndpoint,\n authorization_response_iss_parameter_supported: provider.responseIssuerMode === \"required\",\n };\n }\n\n // oxlint-disable-next-line no-restricted-properties -- Discovered foreign metadata is not yet validated for this adapter profile.\n const metadata = yield* Schema.decodeUnknownEffect(metadataSchema)(raw).pipe(\n Effect.mapError(() => configError(\"metadata\")),\n );\n\n const allowedUrls = yield* Effect.try({\n try: () => {\n if (metadata.issuer !== provider.issuer) throw configError(\"issuer\");\n if (\n (metadata.authorization_response_iss_parameter_supported === true) !==\n (provider.responseIssuerMode === \"required\")\n )\n throw configError(\"metadata\");\n const auth = endpoint(metadata.authorization_endpoint);\n\n for (const key of auth.searchParams.keys()) {\n if (reserved.has(key.toLowerCase())) throw configError(\"parameters\");\n }\n const token = endpoint(metadata.token_endpoint);\n\n const supportedAuthentication =\n metadata.token_endpoint_auth_methods_supported ??\n (provider.protocol === \"oidc\" ? [\"client_secret_basic\"] : undefined);\n\n if (\n supportedAuthentication !== undefined &&\n !supportedAuthentication.includes(provider.authentication.method)\n )\n throw configError(\"authentication\");\n const urls = new Set([token.href]);\n\n if (provider.protocol === \"oidc\") {\n if (\n !metadata.code_challenge_methods_supported?.includes(\"S256\") ||\n !metadata.response_types_supported?.includes(\"code\") ||\n !metadata.id_token_signing_alg_values_supported?.includes(\"RS256\") ||\n metadata.jwks_uri === undefined\n )\n throw configError(\"metadata\");\n urls.add(endpoint(metadata.jwks_uri).href);\n } else {\n urls.add(endpoint(provider.identitySource.url).href);\n }\n freezeOAuth(metadata);\n\n return urls;\n },\n catch: (error) =>\n Schema.is(OpenIdClientConfigurationError)(error) ? error : configError(\"metadata\"),\n });\n\n const serverMetadata: client.ServerMetadata = {\n ...metadata,\n code_challenge_methods_supported: metadata.code_challenge_methods_supported?.slice(),\n response_types_supported: metadata.response_types_supported?.slice(),\n id_token_signing_alg_values_supported:\n metadata.id_token_signing_alg_values_supported?.slice(),\n token_endpoint_auth_methods_supported:\n metadata.token_endpoint_auth_methods_supported?.slice(),\n };\n\n // The SDK encodes each generated 32-byte state/challenge/nonce in 43 URL-safe characters.\n const placeholder = \"a\".repeat(43);\n\n const authorization = yield* Effect.try({\n try: () => new client.Configuration(serverMetadata, provider.clientId),\n catch: () => configError(\"parameters\"),\n });\n\n for (const callback of provider.callbacks) {\n const url = yield* Effect.try({\n try: () =>\n client.buildAuthorizationUrl(\n authorization,\n makeAuthorizationParameters(provider, callback.redirectUri, {\n state: placeholder,\n challenge: placeholder,\n ...(provider.protocol === \"oidc\" ? { nonce: placeholder } : {}),\n }),\n ),\n catch: () => configError(\"parameters\"),\n });\n\n yield* Schema.decodeEffect(OAuthAuthorizationUrl)(url.href).pipe(\n Effect.mapError(() => configError(\"parameters\")),\n );\n }\n freezeOAuth(serverMetadata);\n installed.push({ provider, metadata: serverMetadata, allowedUrls });\n }\n\n return { installed, fetch, timeoutSeconds: options.timeoutSeconds };\n});\n"],"mappings":";;;;;;;;;AAsBA,MAAM,iBAAiB,YACrB,OAAO,OAAO,MAAM,OAAO,YAAY,CAAC,GAAG,OAAO,YAAY,OAAO,CAAC;AAExE,MAAM,SAAS,OAAO,OACpB,OAAO,OAAO,MAAM,OAAO,UAAU,iCAAiC,CAAC,GACvE,OAAO,OAAO,MAAM,OAAO,YAAY,IAAI,CAAC,CAC9C,CAAC,CAAC,MAAM,OAAO,YAAY,WAAW,OAAO,KAAK,MAAM,CAAC,CAAC,UAAU,EAAE,CAAC;AAEvE,MAAM,SAAS,OAAO,kBAAkB,cAAc,IAAI,CAAC;AAE3D,MAAM,iBAAiB,OAAO,MAAM;CAClC,OAAO,OAAO;EAAE,QAAQ,OAAO,QAAQ,qBAAqB;EAAG;CAAO,CAAC;CACvE,OAAO,OAAO;EAAE,QAAQ,OAAO,QAAQ,oBAAoB;EAAG;CAAO,CAAC;CACtE,OAAO,OAAO;EAAE,QAAQ,OAAO,QAAQ,MAAM;EAAG,cAAc,OAAO,QAAQ,IAAI;CAAE,CAAC;AACtF,CAAC;AAED,MAAM,SAAS;CACb,UAAU;CACV,yBAAyB;CACzB,UAAU,OAAO,SAAS,CAAC,UAAU,SAAS,CAAC;CAC/C,QAAQ;CACR,oBAAoB,OAAO,SAAS,CAAC,YAAY,aAAa,CAAC;CAC/D,UAAU,cAAc,IAAI;CAC5B;CACA,WAAW,OAAO,MAChB,OAAO,OAAO;EAAE,YAAY;EAAiB,aAAa;CAAiB,CAAC,CAC9E,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,GAAG,OAAO,YAAY,EAAE,CAAC;CACrD,QAAQ,OAAO,MACb,OAAO,OAAO,MAAM,OAAO,UAAU,mCAAmC,CAAC,CAC3E,CAAC,CAAC,MAAM,OAAO,YAAY,EAAE,CAAC;CAC9B,yBAAyB,OAAO,YAAY,MAAM;CAClD,iBAAiB,OAAO,YAAY,MAAM;AAC5C;AAEA,MAAM,sBACJ,OAAO,OACL,OAAO,OAAO;CACZ,WAAW,OAAO,MAChB,OAAO,MAAM,CACX,OAAO,OAAO;EACZ,GAAG;EACH,UAAU,OAAO,QAAQ,MAAM;EAC/B,0BAA0B,OAAO,QAAQ,OAAO;EAChD,eAAe,OAAO,YACpB,OAAO,IAAI,MAAM,OAAO,UAAU;GAAE,SAAS;GAAG,SAAS;EAAM,CAAC,CAAC,CACnE;CACF,CAAC,GACD,OAAO,OAAO;EACZ,GAAG;EACH,UAAU,OAAO,QAAQ,OAAO;EAChC,uBAAuB,cAAc,IAAI;EACzC,eAAe,cAAc,IAAI;EACjC,UAAU,OAAO,QAAQ,IAAI;EAC7B,gBAAgB,OAAO,OAAO;GAC5B,KAAK,cAAc,IAAI;GACvB,SAAS,OAAO,YAAY,MAAM;GAElC,gBAAgB,OAAO,SAInB,UAEA,UAAU,WAAW,KAAK,CAC9B;EACF,CAAC;CACH,CAAC,CACH,CAAC,CACH,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,GAAG,OAAO,YAAY,EAAE,CAAC;CACrD,gBAAgB,OAAO,OAAO,MAAM,OAAO,UAAU;EAAE,SAAS;EAAG,SAAS;CAAG,CAAC,CAAC;CACjF,OAAO,OAAO,YACZ,OAAO,SAA6B,UAClC,UAAU,WAAW,KAAK,CAC5B,CACF;AACF,CAAC,CACH;AAEF,MAAM,2BAAW,IAAI,IAAI;CACvB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,mCAAmB,IAAI,IAAI;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAM,eAAe,WACnB,+BAA+B,KAAK,EAAE,OAAO,CAAC;AAEhD,MAAa,YAAY,UAAuB;CAC9C,MAAM,MAAM,IAAI,IAAI,KAAK;CAEzB,IACE,IAAI,aAAa,YACjB,IAAI,aAAa,MACjB,IAAI,aAAa,MACjB,MAAM,SAAS,GAAG,KAElB,6BAA6B,KAAK,KAAK,GAEvC,MAAM,YAAY,UAAU;CAE9B,OAAO;AACT;AAEA,MAAM,mBAAmB,eAA6D;CACpF,KAAK,MAAM,OAAO,OAAO,KAAK,cAAc,CAAC,CAAC,GAC5C,IAAI,SAAS,IAAI,IAAI,YAAY,CAAC,GAAG,MAAM,YAAY,YAAY;AAEvE;AAEA,MAAa,wBACX,mBACsB;CACtB,QAAQ,eAAe,QAAvB;EACE,KAAK,uBACH,OAAO,OAAO,kBAAkB,SAAS,MAAM,eAAe,MAAM,CAAC;EACvE,KAAK,sBACH,OAAO,OAAO,iBAAiB,SAAS,MAAM,eAAe,MAAM,CAAC;EACtE,KAAK,QACH,OAAO,OAAO,KAAK;CACvB;AACF;AAUA,MAAa,+BACX,eAMA,aACA,eAC4B;CAC5B,GAAG,cAAc;CACjB,eAAe;CACf,eAAe;CACf,cAAc;CACd,OAAO,cAAc,OAAO,KAAK,GAAG;CACpC,OAAO,UAAU;CACjB,gBAAgB,UAAU;CAC1B,uBAAuB;CACvB,GAAI,UAAU,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,UAAU,MAAM;CAClE,GAAI,cAAc,aAAa,UAAU,cAAc,kBAAkB,KAAA,IACrE,EAAE,SAAS,OAAO,cAAc,aAAa,EAAE,IAC/C,CAAC;AACP;AAEA,MAAM,iBAAiB,OAAO,OAAO;CACnC,QAAQ;CACR,wBAAwB,cAAc,IAAI;CAC1C,gBAAgB,cAAc,IAAI;CAClC,UAAU,OAAO,YAAY,cAAc,IAAI,CAAC;CAChD,kCAAkC,OAAO,YAAY,OAAO,MAAM,cAAc,EAAE,CAAC,CAAC;CACpF,0BAA0B,OAAO,YAAY,OAAO,MAAM,cAAc,EAAE,CAAC,CAAC;CAC5E,uCAAuC,OAAO,YAAY,OAAO,MAAM,cAAc,EAAE,CAAC,CAAC;CACzF,uCAAuC,OAAO,YAAY,OAAO,MAAM,cAAc,EAAE,CAAC,CAAC;CACzF,gDAAgD,OAAO,YAAY,OAAO,OAAO;AACnF,CAAC;AAED,MAAa,wBAAwB,OAAO,GAAG,oCAAoC,CAAC,CAAC,WACnF,OACA;CACA,MAAM,UAAU,OAAO,OAAO,aAAa,cAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KACpE,OAAO,eAAe,YAAY,UAAU,CAAC,CAC/C;CAGA,MAAM,YAAY,QAAQ,UAAU,KAAK,aAA0B;EACjE,MAAM,WAAW;GACf,WAAW,SAAS,UAAU,KAAK,cAAc,EAAE,GAAG,SAAS,EAAE;GACjE,QAAQ,CAAC,GAAG,SAAS,MAAM;GAC3B,GAAI,SAAS,4BAA4B,KAAA,IACrC,CAAC,IACD,EAAE,yBAAyB,EAAE,GAAG,SAAS,wBAAwB,EAAE;GACvE,GAAI,SAAS,oBAAoB,KAAA,IAC7B,CAAC,IACD,EAAE,iBAAiB,EAAE,GAAG,SAAS,gBAAgB,EAAE;GACvD,gBACE,SAAS,eAAe,WAAW,SAC/B,EAAE,GAAG,SAAS,eAAe,IAC7B;IACE,GAAG,SAAS;IACZ,QAAQ,SAAS,KAAK,SAAS,MAAM,SAAS,eAAe,MAAM,CAAC;GACtE;EACR;EAEA,OAAO,SAAS,aAAa,SACzB;GAAE,GAAG;GAAU,GAAG;EAAS,IAC3B;GACE,GAAG;GACH,GAAG;GACH,gBAAgB;IACd,GAAG,SAAS;IACZ,GAAI,SAAS,eAAe,YAAY,KAAA,IACpC,CAAC,IACD,EAAE,SAAS,EAAE,GAAG,SAAS,eAAe,QAAQ,EAAE;GACxD;EACF;CACN,CAAC;CAED,MAAM,QACJ,QAAQ,WACN,KAAK,SACL,WAAW,MAAM,KAAK;EACpB,GAAG;EACH,MAAM,KAAK,gBAAgB,aAAa,IAAI,WAAW,KAAK,IAAI,IAAI,KAAK;CAC3E,CAAC;CAEL,OAAO,OAAO,IAAI;EAChB,WAAW;GACT,MAAM,8BAAc,IAAI,IAAY;GACpC,MAAM,yBAAS,IAAI,IAAY;GAC/B,MAAM,wBAAQ,IAAI,IAAY;GAE9B,KAAK,MAAM,YAAY,WAAW;IAChC,MAAM,aAAa,GAAG,SAAS,SAAS,OAAO,GAAG,SAAS,SAAS,GAAG,SAAS;IAEhF,IAAI,YAAY,IAAI,UAAU,GAAG,MAAM,YAAY,YAAY;IAC/D,YAAY,IAAI,UAAU;IAC1B,MAAM,IAAI,SAAS,QAAQ;IAC3B,IAAI,SAAS,aAAa,UAAU;KAClC,IAAI,OAAO,IAAI,SAAS,QAAQ,GAAG,MAAM,YAAY,YAAY;KACjE,OAAO,IAAI,SAAS,QAAQ;IAC9B;IACA,MAAM,SAAS,SAAS,SAAS,MAAM;IAEvC,IAAI,SAAS,OAAO,SAAS,GAAG,KAAK,OAAO,SAAS,SAAS,eAAe,GAC3E,MAAM,YAAY,QAAQ;IAC5B,IAAI,IAAI,IAAI,SAAS,MAAM,CAAC,CAAC,SAAS,SAAS,OAAO,QACpD,MAAM,YAAY,YAAY;IAChC,IAAK,SAAS,aAAa,WAAY,SAAS,OAAO,SAAS,QAAQ,GACtE,MAAM,YAAY,YAAY;IAChC,gBAAgB,SAAS,uBAAuB;IAChD,gBAAgB,SAAS,eAAe;IACxC,MAAM,4BAAY,IAAI,IAAY;IAElC,KAAK,MAAM,YAAY,SAAS,WAAW;KAGzC,IAFY,SAAS,SAAS,WAG1B,CAAC,CAAC,SAAS,SAAS,eACtB,SAAS,YAAY,SAAS,GAAG,KACjC,UAAU,IAAI,SAAS,UAAU,GAEjC,MAAM,YAAY,UAAU;KAC9B,UAAU,IAAI,SAAS,UAAU;KACjC,KAAK,MAAM,SAAS,WAAW;MAC7B,IAAI,SAAS,WAAW,MAAM,QAAQ;MACtC,IACE,SAAS,uBAAuB,cAChC,MAAM,uBAAuB,YAE7B;MACF,IAAI,MAAM,UAAU,MAAM,cAAc,UAAU,gBAAgB,SAAS,WAAW,GACpF,MAAM,YAAY,UAAU;KAChC;IACF;IACA,IAAI,SAAS,aAAa,SAAS;KACjC,SAAS,SAAS,eAAe,GAAG;KACpC,KAAK,MAAM,OAAO,OAAO,KAAK,SAAS,eAAe,WAAW,CAAC,CAAC,GACjE,IAAI,iBAAiB,IAAI,IAAI,YAAY,CAAC,GAAG,MAAM,YAAY,iBAAiB;KAElF,IAAI,QAAQ,SAAS,eAAe,OAAO;IAC7C;IACA,YAAY,QAAQ;GACtB;GACA,IAAI,OAAO,SAAS,MAAM,MAAM,MAAM,YAAY,YAAY;EAChE;EACA,QAAQ,UACN,OAAO,GAAG,8BAA8B,CAAC,CAAC,KAAK,IAAI,QAAQ,YAAY,UAAU;CACrF,CAAC;CACD,MAAM,YAAoC,CAAC;CAE3C,KAAK,MAAM,YAAY,WAAW;EAChC,IAAI;EAEJ,IAAI,SAAS,aAAa,QAAQ;GAChC,MAAM,eAAe,IAAI,IAAI,SAAS,MAAM;GAE5C,aAAa,WAAW,GAAG,aAAa,SAAS,QAAQ,QAAQ,EAAE,EAAE;GAsBrE,OAAM,OApBuB,OAAO,WAAW;IAC7C,MAAM,WACJ,OAAO,UACL,IAAI,IAAI,SAAS,MAAM,GACvB,SAAS,UACT;KACE,8BAA8B,SAAS;MACtC,OAAO,YAAY;MACnB,OAAO,iBAAiB;IAC3B,GACA,qBAAqB,SAAS,cAAc,GAC5C;KACE,SAAS,QAAQ;KACjB,SAAS,CAAC,OAAO,0BAA0B;MAC1C,OAAO,cAAc,aAAa,OAAO,wBAAQ,IAAI,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;IAChF,CACF;IACF,aAAa,iBAAiB,KAAK,CAAC,CAAC;GACvC,CAAC,EAAA,CAEmB,eAAe;EACrC,OACE,MAAM;GACJ,QAAQ,SAAS;GACjB,wBAAwB,SAAS;GACjC,gBAAgB,SAAS;GACzB,gDAAgD,SAAS,uBAAuB;EAClF;EAIF,MAAM,WAAW,OAAO,OAAO,oBAAoB,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,KACtE,OAAO,eAAe,YAAY,UAAU,CAAC,CAC/C;EAEA,MAAM,cAAc,OAAO,OAAO,IAAI;GACpC,WAAW;IACT,IAAI,SAAS,WAAW,SAAS,QAAQ,MAAM,YAAY,QAAQ;IACnE,IACG,SAAS,mDAAmD,UAC5D,SAAS,uBAAuB,aAEjC,MAAM,YAAY,UAAU;IAC9B,MAAM,OAAO,SAAS,SAAS,sBAAsB;IAErD,KAAK,MAAM,OAAO,KAAK,aAAa,KAAK,GACvC,IAAI,SAAS,IAAI,IAAI,YAAY,CAAC,GAAG,MAAM,YAAY,YAAY;IAErE,MAAM,QAAQ,SAAS,SAAS,cAAc;IAE9C,MAAM,0BACJ,SAAS,0CACR,SAAS,aAAa,SAAS,CAAC,qBAAqB,IAAI,KAAA;IAE5D,IACE,4BAA4B,KAAA,KAC5B,CAAC,wBAAwB,SAAS,SAAS,eAAe,MAAM,GAEhE,MAAM,YAAY,gBAAgB;IACpC,MAAM,uBAAO,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC;IAEjC,IAAI,SAAS,aAAa,QAAQ;KAChC,IACE,CAAC,SAAS,kCAAkC,SAAS,MAAM,KAC3D,CAAC,SAAS,0BAA0B,SAAS,MAAM,KACnD,CAAC,SAAS,uCAAuC,SAAS,OAAO,KACjE,SAAS,aAAa,KAAA,GAEtB,MAAM,YAAY,UAAU;KAC9B,KAAK,IAAI,SAAS,SAAS,QAAQ,CAAC,CAAC,IAAI;IAC3C,OACE,KAAK,IAAI,SAAS,SAAS,eAAe,GAAG,CAAC,CAAC,IAAI;IAErD,YAAY,QAAQ;IAEpB,OAAO;GACT;GACA,QAAQ,UACN,OAAO,GAAG,8BAA8B,CAAC,CAAC,KAAK,IAAI,QAAQ,YAAY,UAAU;EACrF,CAAC;EAED,MAAM,iBAAwC;GAC5C,GAAG;GACH,kCAAkC,SAAS,kCAAkC,MAAM;GACnF,0BAA0B,SAAS,0BAA0B,MAAM;GACnE,uCACE,SAAS,uCAAuC,MAAM;GACxD,uCACE,SAAS,uCAAuC,MAAM;EAC1D;EAGA,MAAM,cAAc,IAAI,OAAO,EAAE;EAEjC,MAAM,gBAAgB,OAAO,OAAO,IAAI;GACtC,WAAW,IAAI,OAAO,cAAc,gBAAgB,SAAS,QAAQ;GACrE,aAAa,YAAY,YAAY;EACvC,CAAC;EAED,KAAK,MAAM,YAAY,SAAS,WAAW;GACzC,MAAM,MAAM,OAAO,OAAO,IAAI;IAC5B,WACE,OAAO,sBACL,eACA,4BAA4B,UAAU,SAAS,aAAa;KAC1D,OAAO;KACP,WAAW;KACX,GAAI,SAAS,aAAa,SAAS,EAAE,OAAO,YAAY,IAAI,CAAC;IAC/D,CAAC,CACH;IACF,aAAa,YAAY,YAAY;GACvC,CAAC;GAED,OAAO,OAAO,aAAa,qBAAqB,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAC1D,OAAO,eAAe,YAAY,YAAY,CAAC,CACjD;EACF;EACA,YAAY,cAAc;EAC1B,UAAU,KAAK;GAAE;GAAU,UAAU;GAAgB;EAAY,CAAC;CACpE;CAEA,OAAO;EAAE;EAAW;EAAO,gBAAgB,QAAQ;CAAe;AACpE,CAAC"}
1
+ {"version":3,"file":"configuration.mjs","names":[],"sources":["../../../src/oauth/openid-client/configuration.ts"],"sourcesContent":["import { Effect, Predicate, Redacted, Schema } from \"effect\";\nimport * as client from \"openid-client\";\n\nimport { OAuthProviderKey } from \"../schema\";\nimport { OAuthUnavailable } from \"../signInErrors\";\nimport {\n OAuthAuthorizationUrl,\n OAuthCallbackId,\n OAuthGeneration,\n OAuthIssuer,\n OAuthRedirectUri,\n} from \"../signInModels\";\nimport { freezeOAuth } from \"../signInSnapshot\";\nimport { TokenCompatibility, tokenCompatibility } from \"./compatibility\";\nimport {\n OpenIdClientConfigurationError,\n type OpenIdClientAuthentication,\n type OpenIdClientOAuthProvider,\n type OpenIdClientOAuthProtocolOptions,\n type OpenIdClientOidcProvider,\n} from \"./models\";\nimport { boundedFetch } from \"./transport\";\n\nconst boundedString = (maximum: number) =>\n Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(maximum));\n\nconst fields = Schema.Record(\n Schema.String.check(Schema.isPattern(/^[A-Za-z][A-Za-z0-9._~-]{0,63}$/)),\n Schema.String.check(Schema.isMaxLength(2048)),\n).check(Schema.makeFilter((record) => Object.keys(record).length <= 16));\n\nconst secret = Schema.RedactedFromValue(boundedString(4096));\n\nconst authentication = Schema.Union([\n Schema.Struct({ method: Schema.Literal(\"client_secret_basic\"), secret }),\n Schema.Struct({ method: Schema.Literal(\"client_secret_post\"), secret }),\n Schema.Struct({ method: Schema.Literal(\"none\"), publicClient: Schema.Literal(true) }),\n]);\n\nconst common = {\n provider: OAuthProviderKey,\n configurationGeneration: OAuthGeneration,\n issuance: Schema.Literals([\"active\", \"retired\"]),\n issuer: OAuthIssuer,\n responseIssuerMode: Schema.Literals([\"required\", \"unsupported\"]),\n clientId: boundedString(1024),\n authentication,\n callbacks: Schema.Array(\n Schema.Struct({ callbackId: OAuthCallbackId, redirectUri: OAuthRedirectUri }),\n ).check(Schema.isMinLength(1), Schema.isMaxLength(16)),\n scopes: Schema.Array(\n Schema.String.check(Schema.isPattern(/^[\\x21\\x23-\\x5b\\x5d-\\x7e]{1,128}$/)),\n ).check(Schema.isMaxLength(32)),\n authorizationParameters: Schema.optionalKey(fields),\n tokenParameters: Schema.optionalKey(fields),\n};\n\nconst optionsSchema = <R>() =>\n Schema.toType(\n Schema.Struct({\n providers: Schema.Array(\n Schema.Union([\n Schema.Struct({\n ...common,\n protocol: Schema.Literal(\"oidc\"),\n idTokenSignedResponseAlg: Schema.Literal(\"RS256\"),\n maxAgeSeconds: Schema.optionalKey(\n Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 86400 })),\n ),\n }),\n Schema.Struct({\n ...common,\n protocol: Schema.Literal(\"oauth\"),\n [tokenCompatibility]: Schema.optionalKey(TokenCompatibility),\n authorizationEndpoint: boundedString(2048),\n tokenEndpoint: boundedString(2048),\n pkceS256: Schema.Literal(true),\n identitySource: Schema.Struct({\n url: boundedString(2048),\n headers: Schema.optionalKey(fields),\n // A configured function is trusted application code; its result has a separate schema boundary.\n decodeIdentity: Schema.declare<\n OpenIdClientOAuthProvider<R>[\"identitySource\"][\"decodeIdentity\"]\n >(\n (\n input,\n ): input is OpenIdClientOAuthProvider<R>[\"identitySource\"][\"decodeIdentity\"] =>\n Predicate.isFunction(input),\n ),\n }),\n }),\n ]),\n ).check(Schema.isMinLength(1), Schema.isMaxLength(64)),\n timeoutSeconds: Schema.Finite.check(Schema.isBetween({ minimum: 1, maximum: 30 })),\n fetch: Schema.optionalKey(\n Schema.declare<client.CustomFetch>((input): input is client.CustomFetch =>\n Predicate.isFunction(input),\n ),\n ),\n }),\n );\n\nconst reserved = new Set([\n \"client_id\",\n \"client_secret\",\n \"client_assertion\",\n \"client_assertion_type\",\n \"redirect_uri\",\n \"response_type\",\n \"response_mode\",\n \"state\",\n \"code\",\n \"code_verifier\",\n \"code_challenge\",\n \"code_challenge_method\",\n \"nonce\",\n \"scope\",\n \"iss\",\n \"grant_type\",\n \"max_age\",\n \"request\",\n \"request_uri\",\n \"authorization_details\",\n \"id_token_hint\",\n \"login_hint\",\n \"login_hint_token\",\n \"subject_token\",\n \"subject_token_type\",\n \"actor_token\",\n \"actor_token_type\",\n \"requested_token_type\",\n]);\n\nconst forbiddenHeaders = new Set([\n \"authorization\",\n \"proxy-authorization\",\n \"cookie\",\n \"host\",\n \"content-length\",\n \"content-type\",\n \"transfer-encoding\",\n \"connection\",\n \"upgrade\",\n \"trailer\",\n \"te\",\n]);\n\nconst configError = (reason: OpenIdClientConfigurationError[\"reason\"]) =>\n OpenIdClientConfigurationError.make({ reason });\n\nexport const endpoint = (value: string): URL => {\n const url = new URL(value);\n\n if (\n url.protocol !== \"https:\" ||\n url.username !== \"\" ||\n url.password !== \"\" ||\n value.includes(\"#\") ||\n // oxlint-disable-next-line no-control-regex -- Reject ambiguous protocol URL control characters.\n /[\\s\\\\\\u0000-\\u001f\\u007f]/u.test(value)\n )\n throw configError(\"metadata\");\n\n return url;\n};\n\nconst checkParameters = (parameters: Readonly<Record<string, string>> | undefined) => {\n for (const key of Object.keys(parameters ?? {})) {\n if (reserved.has(key.toLowerCase())) throw configError(\"parameters\");\n }\n};\n\nexport const clientAuthentication = (\n authentication: OpenIdClientAuthentication,\n): client.ClientAuth => {\n switch (authentication.method) {\n case \"client_secret_basic\":\n return client.ClientSecretBasic(Redacted.value(authentication.secret));\n case \"client_secret_post\":\n return client.ClientSecretPost(Redacted.value(authentication.secret));\n case \"none\":\n return client.None();\n }\n};\n\nexport type Provider<R> = OpenIdClientOidcProvider | OpenIdClientOAuthProvider<R>;\n\nexport interface InstalledProvider<R> {\n readonly provider: Provider<R>;\n readonly metadata: client.ServerMetadata;\n readonly allowedUrls: ReadonlySet<string>;\n}\n\nexport const makeAuthorizationParameters = (\n configuration: {\n readonly protocol: \"oauth\" | \"oidc\";\n readonly authorizationParameters?: Readonly<Record<string, string>>;\n readonly scopes: ReadonlyArray<string>;\n readonly maxAgeSeconds?: number;\n },\n redirectUri: string,\n generated: { readonly state: string; readonly challenge: string; readonly nonce?: string },\n): Record<string, string> => ({\n ...configuration.authorizationParameters,\n response_type: \"code\",\n response_mode: \"query\",\n redirect_uri: redirectUri,\n scope: configuration.scopes.join(\" \"),\n state: generated.state,\n code_challenge: generated.challenge,\n code_challenge_method: \"S256\",\n ...(generated.nonce === undefined ? {} : { nonce: generated.nonce }),\n ...(configuration.protocol === \"oidc\" && configuration.maxAgeSeconds !== undefined\n ? { max_age: String(configuration.maxAgeSeconds) }\n : {}),\n});\n\nconst metadataSchema = Schema.Struct({\n issuer: OAuthIssuer,\n authorization_endpoint: boundedString(2048),\n token_endpoint: boundedString(2048),\n jwks_uri: Schema.optionalKey(boundedString(2048)),\n code_challenge_methods_supported: Schema.optionalKey(Schema.Array(boundedString(64))),\n response_types_supported: Schema.optionalKey(Schema.Array(boundedString(64))),\n id_token_signing_alg_values_supported: Schema.optionalKey(Schema.Array(boundedString(64))),\n token_endpoint_auth_methods_supported: Schema.optionalKey(Schema.Array(boundedString(64))),\n authorization_response_iss_parameter_supported: Schema.optionalKey(Schema.Boolean),\n});\n\nexport const installConfigurations = Effect.fn(\"OpenIdClient.installConfigurations\")(function* <R>(\n input: OpenIdClientOAuthProtocolOptions<R>,\n) {\n const options = yield* Schema.decodeEffect(optionsSchema<R>())(input).pipe(\n Effect.mapError(() => configError(\"provider\")),\n );\n\n // Detach secrets as well as arrays and records before retaining configuration.\n const providers = options.providers.map((provider): Provider<R> => {\n const detached = {\n callbacks: provider.callbacks.map((callback) => ({ ...callback })),\n scopes: [...provider.scopes],\n ...(provider.authorizationParameters === undefined\n ? {}\n : { authorizationParameters: { ...provider.authorizationParameters } }),\n ...(provider.tokenParameters === undefined\n ? {}\n : { tokenParameters: { ...provider.tokenParameters } }),\n authentication:\n provider.authentication.method === \"none\"\n ? { ...provider.authentication }\n : {\n ...provider.authentication,\n secret: Redacted.make(Redacted.value(provider.authentication.secret)),\n },\n };\n\n return provider.protocol === \"oidc\"\n ? { ...provider, ...detached }\n : {\n ...provider,\n ...detached,\n identitySource: {\n ...provider.identitySource,\n ...(provider.identitySource.headers === undefined\n ? {}\n : { headers: { ...provider.identitySource.headers } }),\n },\n };\n });\n\n const fetch: client.CustomFetch =\n options.fetch ??\n ((url, init) =>\n globalThis.fetch(url, {\n ...init,\n body: init.body instanceof Uint8Array ? new Uint8Array(init.body) : init.body,\n }));\n\n yield* Effect.try({\n try: () => {\n const generations = new Set<string>();\n const active = new Set<string>();\n const names = new Set<string>();\n\n for (const provider of providers) {\n const generation = `${provider.provider.length}:${provider.provider}:${provider.configurationGeneration}`;\n\n if (generations.has(generation)) throw configError(\"generation\");\n generations.add(generation);\n names.add(provider.provider);\n if (provider.issuance === \"active\") {\n if (active.has(provider.provider)) throw configError(\"generation\");\n active.add(provider.provider);\n }\n const issuer = endpoint(provider.issuer);\n\n if (provider.issuer.includes(\"?\") || issuer.pathname.includes(\"/.well-known/\"))\n throw configError(\"issuer\");\n if (new Set(provider.scopes).size !== provider.scopes.length)\n throw configError(\"parameters\");\n if ((provider.protocol === \"oidc\") !== provider.scopes.includes(\"openid\"))\n throw configError(\"parameters\");\n checkParameters(provider.authorizationParameters);\n checkParameters(provider.tokenParameters);\n const callbacks = new Set<string>();\n\n for (const callback of provider.callbacks) {\n const url = endpoint(callback.redirectUri);\n\n if (\n url.href !== callback.redirectUri ||\n callback.redirectUri.includes(\"?\") ||\n callbacks.has(callback.callbackId)\n )\n throw configError(\"callback\");\n callbacks.add(callback.callbackId);\n for (const other of providers) {\n if (provider.issuer === other.issuer) continue;\n if (\n provider.responseIssuerMode === \"required\" &&\n other.responseIssuerMode === \"required\"\n )\n continue;\n if (other.callbacks.some((candidate) => candidate.redirectUri === callback.redirectUri))\n throw configError(\"callback\");\n }\n }\n if (provider.protocol === \"oauth\") {\n endpoint(provider.identitySource.url);\n for (const key of Object.keys(provider.identitySource.headers ?? {})) {\n if (forbiddenHeaders.has(key.toLowerCase())) throw configError(\"identity-source\");\n }\n new Headers(provider.identitySource.headers);\n }\n freezeOAuth(provider);\n }\n if (active.size !== names.size) throw configError(\"generation\");\n },\n catch: (error) =>\n Schema.is(OpenIdClientConfigurationError)(error) ? error : configError(\"provider\"),\n });\n const installed: InstalledProvider<R>[] = [];\n\n for (const provider of providers) {\n let raw: client.ServerMetadata;\n\n if (provider.protocol === \"oidc\") {\n const discoveryUrl = new URL(provider.issuer);\n\n discoveryUrl.pathname = `${discoveryUrl.pathname.replace(/\\/$/u, \"\")}/.well-known/openid-configuration`;\n\n const configuration = yield* Effect.tryPromise({\n try: (signal) =>\n client.discovery(\n new URL(provider.issuer),\n provider.clientId,\n {\n id_token_signed_response_alg: provider.idTokenSignedResponseAlg,\n [client.clockSkew]: 0,\n [client.clockTolerance]: 0,\n },\n clientAuthentication(provider.authentication),\n {\n timeout: options.timeoutSeconds,\n execute: [client.enableNonRepudiationChecks],\n [client.customFetch]: boundedFetch(fetch, signal, new Set([discoveryUrl.href])),\n },\n ),\n catch: () => OAuthUnavailable.make({}),\n });\n\n raw = configuration.serverMetadata();\n } else {\n raw = {\n issuer: provider.issuer,\n authorization_endpoint: provider.authorizationEndpoint,\n token_endpoint: provider.tokenEndpoint,\n authorization_response_iss_parameter_supported: provider.responseIssuerMode === \"required\",\n };\n }\n\n // oxlint-disable-next-line no-restricted-properties -- Discovered foreign metadata is not yet validated for this adapter profile.\n const metadata = yield* Schema.decodeUnknownEffect(metadataSchema)(raw).pipe(\n Effect.mapError(() => configError(\"metadata\")),\n );\n\n const allowedUrls = yield* Effect.try({\n try: () => {\n if (metadata.issuer !== provider.issuer) throw configError(\"issuer\");\n if (\n (metadata.authorization_response_iss_parameter_supported === true) !==\n (provider.responseIssuerMode === \"required\")\n )\n throw configError(\"metadata\");\n const auth = endpoint(metadata.authorization_endpoint);\n\n for (const key of auth.searchParams.keys()) {\n if (reserved.has(key.toLowerCase())) throw configError(\"parameters\");\n }\n const token = endpoint(metadata.token_endpoint);\n\n const supportedAuthentication =\n metadata.token_endpoint_auth_methods_supported ??\n (provider.protocol === \"oidc\" ? [\"client_secret_basic\"] : undefined);\n\n if (\n supportedAuthentication !== undefined &&\n !supportedAuthentication.includes(provider.authentication.method)\n )\n throw configError(\"authentication\");\n const urls = new Set([token.href]);\n\n if (provider.protocol === \"oidc\") {\n if (\n !metadata.code_challenge_methods_supported?.includes(\"S256\") ||\n !metadata.response_types_supported?.includes(\"code\") ||\n !metadata.id_token_signing_alg_values_supported?.includes(\"RS256\") ||\n metadata.jwks_uri === undefined\n )\n throw configError(\"metadata\");\n urls.add(endpoint(metadata.jwks_uri).href);\n } else {\n urls.add(endpoint(provider.identitySource.url).href);\n }\n freezeOAuth(metadata);\n\n return urls;\n },\n catch: (error) =>\n Schema.is(OpenIdClientConfigurationError)(error) ? error : configError(\"metadata\"),\n });\n\n const serverMetadata: client.ServerMetadata = {\n ...metadata,\n code_challenge_methods_supported: metadata.code_challenge_methods_supported?.slice(),\n response_types_supported: metadata.response_types_supported?.slice(),\n id_token_signing_alg_values_supported:\n metadata.id_token_signing_alg_values_supported?.slice(),\n token_endpoint_auth_methods_supported:\n metadata.token_endpoint_auth_methods_supported?.slice(),\n };\n\n // The SDK encodes each generated 32-byte state/challenge/nonce in 43 URL-safe characters.\n const placeholder = \"a\".repeat(43);\n\n const authorization = yield* Effect.try({\n try: () => new client.Configuration(serverMetadata, provider.clientId),\n catch: () => configError(\"parameters\"),\n });\n\n for (const callback of provider.callbacks) {\n const url = yield* Effect.try({\n try: () =>\n client.buildAuthorizationUrl(\n authorization,\n makeAuthorizationParameters(provider, callback.redirectUri, {\n state: placeholder,\n challenge: placeholder,\n ...(provider.protocol === \"oidc\" ? { nonce: placeholder } : {}),\n }),\n ),\n catch: () => configError(\"parameters\"),\n });\n\n yield* Schema.decodeEffect(OAuthAuthorizationUrl)(url.href).pipe(\n Effect.mapError(() => configError(\"parameters\")),\n );\n }\n freezeOAuth(serverMetadata);\n installed.push({ provider, metadata: serverMetadata, allowedUrls });\n }\n\n return { installed, fetch, timeoutSeconds: options.timeoutSeconds };\n});\n"],"mappings":"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"}
@@ -3,9 +3,9 @@ import { OAuthUnavailable } from "../../signInErrors.mjs";
3
3
  import "../../signInModels.mjs";
4
4
  import "../../connectedModels.mjs";
5
5
  import { OAuthConnectedProtocol } from "../../OAuthConnectedProtocol.mjs";
6
- import { OpenIdClientConfigurationError } from "../models.mjs";
7
6
  import { OpenIdClientConnectedProtocolOptions } from "./models.mjs";
8
7
  import "../compatibility.mjs";
8
+ import { OpenIdClientConfigurationError } from "../models.mjs";
9
9
  import "../ProviderRevocation.mjs";
10
10
  import { DateTime, Effect, Layer } from "effect";
11
11
  //#region src/oauth/openid-client/connected/protocol.d.ts
@@ -1,5 +1,6 @@
1
1
  import { OAuthProtocolRejected } from "../signInErrors.mjs";
2
2
  import { OAuthProtocolConfiguration, OAuthVerifiedExternalIdentity } from "../signInModels.mjs";
3
+ import { TokenCompatibility, tokenCompatibility } from "./compatibility.mjs";
3
4
  import { Effect, Redacted, Schema } from "effect";
4
5
  import { CustomFetch } from "openid-client";
5
6
  //#region src/oauth/openid-client/models.d.ts
@@ -44,6 +45,8 @@ interface OpenIdClientOidcProvider extends ProviderGeneration {
44
45
  readonly maxAgeSeconds?: number;
45
46
  }
46
47
  interface OpenIdClientOAuthProvider<R = never> extends ProviderGeneration {
48
+ /** @internal First-party provider behavior, retained by the configuration codec. */
49
+ readonly [tokenCompatibility]?: TokenCompatibility;
47
50
  readonly protocol: "oauth";
48
51
  readonly authorizationEndpoint: string;
49
52
  readonly tokenEndpoint: string;
@@ -1 +1 @@
1
- {"version":3,"file":"models.mjs","names":[],"sources":["../../../src/oauth/openid-client/models.ts"],"sourcesContent":["import { type Effect, type Redacted, Schema } from \"effect\";\nimport type { CustomFetch } from \"openid-client\";\n\nimport type { OAuthProtocolRejected } from \"../signInErrors\";\nimport type { OAuthProtocolConfiguration, OAuthVerifiedExternalIdentity } from \"../signInModels\";\n\nexport class OpenIdClientConfigurationError extends Schema.TaggedError<OpenIdClientConfigurationError>()(\n \"OpenIdClientConfigurationError\",\n {\n reason: Schema.Literals([\n \"provider\",\n \"generation\",\n \"issuer\",\n \"callback\",\n \"authentication\",\n \"parameters\",\n \"metadata\",\n \"identity-source\",\n ]),\n },\n) {}\n\nexport type OpenIdClientAuthentication =\n | { readonly method: \"client_secret_basic\"; readonly secret: Redacted.Redacted<string> }\n | { readonly method: \"client_secret_post\"; readonly secret: Redacted.Redacted<string> }\n | { readonly method: \"none\"; readonly publicClient: true };\n\nexport interface PlainOAuthIdentity {\n readonly subject: string;\n readonly profile?: OAuthVerifiedExternalIdentity[\"profile\"];\n}\n\ninterface ProviderGeneration {\n readonly provider: OAuthProtocolConfiguration[\"provider\"];\n readonly configurationGeneration: OAuthProtocolConfiguration[\"configurationGeneration\"];\n readonly issuance: \"active\" | \"retired\";\n /** Preserve this exact issuer identifier, including an optional trailing slash. */\n readonly issuer: OAuthProtocolConfiguration[\"issuer\"];\n readonly responseIssuerMode: OAuthProtocolConfiguration[\"responseIssuerMode\"];\n readonly clientId: string;\n readonly authentication: OpenIdClientAuthentication;\n readonly callbacks: ReadonlyArray<{\n readonly callbackId: OAuthProtocolConfiguration[\"callbackId\"];\n readonly redirectUri: OAuthProtocolConfiguration[\"redirectUri\"];\n }>;\n readonly scopes: ReadonlyArray<string>;\n readonly authorizationParameters?: Readonly<Record<string, string>>;\n readonly tokenParameters?: Readonly<Record<string, string>>;\n}\n\nexport interface OpenIdClientOidcProvider extends ProviderGeneration {\n readonly protocol: \"oidc\";\n readonly idTokenSignedResponseAlg: \"RS256\";\n readonly maxAgeSeconds?: number;\n}\n\nexport interface OpenIdClientOAuthProvider<R = never> extends ProviderGeneration {\n readonly protocol: \"oauth\";\n readonly authorizationEndpoint: string;\n readonly tokenEndpoint: string;\n readonly pkceS256: true;\n readonly identitySource: {\n readonly url: string;\n readonly headers?: Readonly<Record<string, string>>;\n /** Receives only the freshly fetched authenticated identity body, never a grant. */\n readonly decodeIdentity: (\n body: unknown,\n ) => Effect.Effect<PlainOAuthIdentity, OAuthProtocolRejected, R>;\n };\n}\n\nexport interface OpenIdClientOAuthProtocolOptions<R = never> {\n readonly providers: ReadonlyArray<OpenIdClientOidcProvider | OpenIdClientOAuthProvider<R>>;\n /** Per-request deadline; the method separately limits the complete exchange. */\n readonly timeoutSeconds: number;\n /** Trusted server transport. Must honor abort and must not retry or log credentials. */\n readonly fetch?: CustomFetch;\n}\n"],"mappings":";;AAMA,IAAa,iCAAb,cAAoD,OAAO,YAA4C,CAAC,CACtG,kCACA,EACE,QAAQ,OAAO,SAAS;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,EACH,CACF,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"models.mjs","names":[],"sources":["../../../src/oauth/openid-client/models.ts"],"sourcesContent":["import { type Effect, type Redacted, Schema } from \"effect\";\nimport type { CustomFetch } from \"openid-client\";\n\nimport type { OAuthProtocolRejected } from \"../signInErrors\";\nimport type { OAuthProtocolConfiguration, OAuthVerifiedExternalIdentity } from \"../signInModels\";\nimport type { TokenCompatibility, tokenCompatibility } from \"./compatibility\";\n\nexport class OpenIdClientConfigurationError extends Schema.TaggedError<OpenIdClientConfigurationError>()(\n \"OpenIdClientConfigurationError\",\n {\n reason: Schema.Literals([\n \"provider\",\n \"generation\",\n \"issuer\",\n \"callback\",\n \"authentication\",\n \"parameters\",\n \"metadata\",\n \"identity-source\",\n ]),\n },\n) {}\n\nexport type OpenIdClientAuthentication =\n | { readonly method: \"client_secret_basic\"; readonly secret: Redacted.Redacted<string> }\n | { readonly method: \"client_secret_post\"; readonly secret: Redacted.Redacted<string> }\n | { readonly method: \"none\"; readonly publicClient: true };\n\nexport interface PlainOAuthIdentity {\n readonly subject: string;\n readonly profile?: OAuthVerifiedExternalIdentity[\"profile\"];\n}\n\ninterface ProviderGeneration {\n readonly provider: OAuthProtocolConfiguration[\"provider\"];\n readonly configurationGeneration: OAuthProtocolConfiguration[\"configurationGeneration\"];\n readonly issuance: \"active\" | \"retired\";\n /** Preserve this exact issuer identifier, including an optional trailing slash. */\n readonly issuer: OAuthProtocolConfiguration[\"issuer\"];\n readonly responseIssuerMode: OAuthProtocolConfiguration[\"responseIssuerMode\"];\n readonly clientId: string;\n readonly authentication: OpenIdClientAuthentication;\n readonly callbacks: ReadonlyArray<{\n readonly callbackId: OAuthProtocolConfiguration[\"callbackId\"];\n readonly redirectUri: OAuthProtocolConfiguration[\"redirectUri\"];\n }>;\n readonly scopes: ReadonlyArray<string>;\n readonly authorizationParameters?: Readonly<Record<string, string>>;\n readonly tokenParameters?: Readonly<Record<string, string>>;\n}\n\nexport interface OpenIdClientOidcProvider extends ProviderGeneration {\n readonly protocol: \"oidc\";\n readonly idTokenSignedResponseAlg: \"RS256\";\n readonly maxAgeSeconds?: number;\n}\n\nexport interface OpenIdClientOAuthProvider<R = never> extends ProviderGeneration {\n /** @internal First-party provider behavior, retained by the configuration codec. */\n readonly [tokenCompatibility]?: TokenCompatibility;\n readonly protocol: \"oauth\";\n readonly authorizationEndpoint: string;\n readonly tokenEndpoint: string;\n readonly pkceS256: true;\n readonly identitySource: {\n readonly url: string;\n readonly headers?: Readonly<Record<string, string>>;\n /** Receives only the freshly fetched authenticated identity body, never a grant. */\n readonly decodeIdentity: (\n body: unknown,\n ) => Effect.Effect<PlainOAuthIdentity, OAuthProtocolRejected, R>;\n };\n}\n\nexport interface OpenIdClientOAuthProtocolOptions<R = never> {\n readonly providers: ReadonlyArray<OpenIdClientOidcProvider | OpenIdClientOAuthProvider<R>>;\n /** Per-request deadline; the method separately limits the complete exchange. */\n readonly timeoutSeconds: number;\n /** Trusted server transport. Must honor abort and must not retry or log credentials. */\n readonly fetch?: CustomFetch;\n}\n"],"mappings":";;AAOA,IAAa,iCAAb,cAAoD,OAAO,YAA4C,CAAC,CACtG,kCACA,EACE,QAAQ,OAAO,SAAS;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,EACH,CACF,CAAC,CAAC,CAAC"}
@@ -5,7 +5,6 @@ import { OAuthProtocolRejected, OAuthRejected, OAuthUnavailable } from "../signI
5
5
  import { OAuthCallbackId, OAuthCodeResponse, OAuthProtocolConfiguration, OAuthProtocolPreparation, OAuthTransactionSecrets, OAuthVerifiedExternalIdentity } from "../signInModels.mjs";
6
6
  import { OAuthProtocol } from "../OAuthProtocol.mjs";
7
7
  import { OpenIdClientConfigurationError, OpenIdClientOAuthProtocolOptions } from "./models.mjs";
8
- import "./compatibility.mjs";
9
8
  import { DateTime, Effect, Layer } from "effect";
10
9
  //#region src/oauth/openid-client/protocol.d.ts
11
10
  declare const makeOpenIdClientOAuthProtocol: <R = never>(options: OpenIdClientOAuthProtocolOptions<R>) => Effect.Effect<{
@@ -5,7 +5,7 @@ import { OAuthCallbackId, OAuthCodeResponse, OAuthDisplayProfile, OAuthProtocolC
5
5
  import { OAuthProtocolRejected, OAuthRejected, OAuthUnavailable } from "../signInErrors.mjs";
6
6
  import { snapshotOAuth } from "../signInSnapshot.mjs";
7
7
  import { OAuthProtocol } from "../OAuthProtocol.mjs";
8
- import { DefiniteTokenRejection } from "./compatibility.mjs";
8
+ import { DefiniteTokenRejection, tokenCompatibility } from "./compatibility.mjs";
9
9
  import { boundedFetch } from "./transport.mjs";
10
10
  import { clientAuthentication, installConfigurations, makeAuthorizationParameters } from "./configuration.mjs";
11
11
  import { Cause, DateTime, Effect, Layer, Redacted, Schema } from "effect";
@@ -55,8 +55,9 @@ const grantError = (error) => {
55
55
  if (error instanceof client.ResponseBodyError && error.status === 400 && error.error === "invalid_grant") return rejected();
56
56
  return unavailable();
57
57
  };
58
- const privateConfiguration = (entry, timeout, fetch, signal, compatibility) => {
58
+ const privateConfiguration = (entry, timeout, fetch, signal) => {
59
59
  const provider = entry.provider;
60
+ const compatibility = provider.protocol === "oauth" ? provider[tokenCompatibility] : void 0;
60
61
  const configuration = new client.Configuration(entry.metadata, provider.clientId, {
61
62
  [client.clockSkew]: 0,
62
63
  [client.clockTolerance]: 0,
@@ -85,7 +86,7 @@ const privateConfiguration = (entry, timeout, fetch, signal, compatibility) => {
85
86
  if (provider.protocol === "oidc") client.enableNonRepudiationChecks(configuration);
86
87
  return configuration;
87
88
  };
88
- const makeOAuthProtocolWithCompatibility = Effect.fn("makeOpenIdClientOAuthProtocol")(function* (options, compatibility) {
89
+ const makeOpenIdClientOAuthProtocol = Effect.fn("makeOpenIdClientOAuthProtocol")(function* (options) {
89
90
  const context = yield* Effect.context();
90
91
  const { installed, fetch, timeoutSeconds } = yield* installConfigurations(options);
91
92
  const prepareAuthorization = Effect.fn("OpenIdClient.prepareAuthorization")(function* (input) {
@@ -96,7 +97,7 @@ const makeOAuthProtocolWithCompatibility = Effect.fn("makeOpenIdClientOAuthProto
96
97
  if (entry === void 0 || provider === void 0 || callback === void 0) return yield* OAuthRejected.make({});
97
98
  const result = yield* Effect.tryPromise({
98
99
  try: async (signal) => {
99
- const configuration = privateConfiguration(entry, timeoutSeconds, fetch, signal, compatibility);
100
+ const configuration = privateConfiguration(entry, timeoutSeconds, fetch, signal);
100
101
  const state = client.randomState();
101
102
  const verifier = client.randomPKCECodeVerifier();
102
103
  const nonce = provider.protocol === "oidc" ? client.randomNonce() : void 0;
@@ -143,7 +144,7 @@ const makeOAuthProtocolWithCompatibility = Effect.fn("makeOpenIdClientOAuthProto
143
144
  if (startedAt < 0 || startedAt > DateTime.toEpochMillis(yield* DateTime.now)) return yield* rejected();
144
145
  const exchanged = yield* Effect.tryPromise({
145
146
  try: async (signal) => {
146
- const configuration = privateConfiguration(entry, timeoutSeconds, fetch, signal, compatibility);
147
+ const configuration = privateConfiguration(entry, timeoutSeconds, fetch, signal);
147
148
  const currentUrl = new URL(saved.redirectUri);
148
149
  currentUrl.searchParams.set("code", Redacted.value(request.response.code));
149
150
  currentUrl.searchParams.set("state", Redacted.value(request.response.state));
@@ -210,9 +211,8 @@ const makeOAuthProtocolWithCompatibility = Effect.fn("makeOpenIdClientOAuthProto
210
211
  exchangeVerifiedIdentity: (input) => unavailableOnDefect(exchangeVerifiedIdentity(input))
211
212
  });
212
213
  }, unavailableOnDefect);
213
- const makeOpenIdClientOAuthProtocol = (options) => makeOAuthProtocolWithCompatibility(options);
214
214
  const openIdClientOAuthProtocolLayer = (options) => Layer.effect(OAuthProtocol, makeOpenIdClientOAuthProtocol(options));
215
215
  //#endregion
216
- export { makeOAuthProtocolWithCompatibility, makeOpenIdClientOAuthProtocol, openIdClientOAuthProtocolLayer };
216
+ export { makeOpenIdClientOAuthProtocol, openIdClientOAuthProtocolLayer };
217
217
 
218
218
  //# sourceMappingURL=protocol.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.mjs","names":[],"sources":["../../../src/oauth/openid-client/protocol.ts"],"sourcesContent":["import { Cause, DateTime, Effect, Layer, Redacted, Schema } from \"effect\";\nimport * as client from \"openid-client\";\n\nimport { reportAuthFailure } from \"../../internal/diagnostics\";\nimport { RequestBindingFlowId } from \"../../operations/requestBinding\";\nimport { OAuthProtocol } from \"../OAuthProtocol\";\nimport { OAuthProviderKey } from \"../schema\";\nimport { OAuthProtocolRejected, OAuthRejected, OAuthUnavailable } from \"../signInErrors\";\nimport {\n OAuthCallbackId,\n OAuthCodeResponse,\n OAuthDisplayProfile,\n OAuthProtocolConfiguration,\n OAuthProtocolPreparation,\n OAuthTransactionSecrets,\n OAuthVerifiedExternalIdentity,\n} from \"../signInModels\";\nimport { snapshotOAuth } from \"../signInSnapshot\";\nimport { DefiniteTokenRejection, type TokenCompatibility } from \"./compatibility\";\nimport {\n clientAuthentication,\n installConfigurations,\n makeAuthorizationParameters,\n type InstalledProvider,\n} from \"./configuration\";\nimport {\n type OpenIdClientConfigurationError,\n type OpenIdClientOAuthProtocolOptions,\n} from \"./models\";\nimport { boundedFetch } from \"./transport\";\n\nconst beginInput = Schema.Struct({\n provider: OAuthProviderKey,\n callbackId: OAuthCallbackId,\n flowId: RequestBindingFlowId,\n});\n\nconst exchangeInput = Schema.toType(\n Schema.Struct({\n configuration: OAuthProtocolConfiguration,\n response: OAuthCodeResponse,\n secrets: OAuthTransactionSecrets,\n verificationStartedAt: Schema.DateTimeUtcFromMillis,\n }),\n);\n\nconst numericDate = Schema.Finite.check(Schema.isBetween({ minimum: 0, maximum: 8640000000000 }));\n\nconst claimsSchema = Schema.Struct({\n iss: Schema.String,\n sub: OAuthVerifiedExternalIdentity.fields.identity.fields.subject,\n aud: Schema.Union([\n Schema.String,\n Schema.Array(Schema.String).check(Schema.isMinLength(1), Schema.isMaxLength(1)),\n ]),\n azp: Schema.optionalKey(Schema.String),\n exp: numericDate,\n iat: numericDate,\n nbf: Schema.optionalKey(numericDate),\n auth_time: Schema.optionalKey(numericDate),\n});\n\nconst plainIdentitySchema = Schema.Struct({\n subject: OAuthVerifiedExternalIdentity.fields.identity.fields.subject,\n profile: Schema.optionalKey(OAuthDisplayProfile),\n});\n\nconst unavailable = () => OAuthUnavailable.make({});\nconst rejected = () => OAuthProtocolRejected.make({});\n\nconst unavailableOnDefect = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n effect.pipe(\n Effect.tapCause((cause) =>\n Cause.hasDies(cause) ? reportAuthFailure(\"oauth-protocol\", cause) : Effect.void,\n ),\n Effect.catchCause((cause): Effect.Effect<never, E | OAuthUnavailable> => {\n if (Cause.hasInterrupts(cause)) return Effect.interrupt;\n if (Cause.hasDies(cause)) return Effect.fail(unavailable());\n\n return Effect.failCause(cause);\n }),\n );\n\n/** Only precise claim errors and a fully parsed invalid_grant are definite.\n * INVALID_RESPONSE also covers signature/key/transport faults; keep it ambiguous. */\nconst grantError = (error: unknown) => {\n if (\n error instanceof DefiniteTokenRejection ||\n (error instanceof client.ClientError && error.cause instanceof DefiniteTokenRejection)\n )\n return rejected();\n if (\n error instanceof client.ClientError &&\n (error.code === \"OAUTH_JWT_CLAIM_COMPARISON_FAILED\" ||\n error.code === \"OAUTH_JWT_TIMESTAMP_CHECK_FAILED\")\n )\n return rejected();\n if (\n error instanceof client.ResponseBodyError &&\n error.status === 400 &&\n error.error === \"invalid_grant\"\n )\n return rejected();\n\n return unavailable();\n};\n\nconst privateConfiguration = <R>(\n entry: InstalledProvider<R>,\n timeout: number,\n fetch: client.CustomFetch,\n signal: AbortSignal,\n compatibility?: TokenCompatibility,\n) => {\n const provider = entry.provider;\n\n const configuration = new client.Configuration(\n entry.metadata,\n provider.clientId,\n {\n [client.clockSkew]: 0,\n [client.clockTolerance]: 0,\n ...(provider.protocol === \"oidc\"\n ? { id_token_signed_response_alg: provider.idTokenSignedResponseAlg }\n : {}),\n },\n clientAuthentication(provider.authentication),\n );\n\n configuration.timeout = timeout;\n const transport = boundedFetch(fetch, signal, entry.allowedUrls);\n\n configuration[client.customFetch] =\n compatibility === undefined\n ? transport\n : async (url, options) => {\n const response = await transport(url, options);\n\n if (url === new URL(entry.metadata.token_endpoint!).href) {\n const body: unknown = await response.clone().json();\n\n signal.throwIfAborted();\n compatibility.inspectReceipt(\n { body, status: response.status, contentType: response.headers.get(\"content-type\") },\n {\n scopes: provider.scopes,\n refreshRequired: false,\n operation: \"authorization_code\",\n },\n );\n signal.throwIfAborted();\n }\n\n return response;\n };\n if (provider.protocol === \"oidc\") client.enableNonRepudiationChecks(configuration);\n\n return configuration;\n};\n\nexport const makeOAuthProtocolWithCompatibility = Effect.fn(\"makeOpenIdClientOAuthProtocol\")(\n function* <R = never>(\n options: OpenIdClientOAuthProtocolOptions<R>,\n compatibility?: TokenCompatibility,\n ): Effect.fn.Return<\n OAuthProtocol[\"Service\"],\n OpenIdClientConfigurationError | OAuthUnavailable,\n R\n > {\n const context = yield* Effect.context<R>();\n const { installed, fetch, timeoutSeconds } = yield* installConfigurations(options);\n\n const prepareAuthorization: OAuthProtocol[\"Service\"][\"prepareAuthorization\"] = Effect.fn(\n \"OpenIdClient.prepareAuthorization\",\n )(function* (input) {\n const request = yield* Schema.decodeEffect(beginInput)(input).pipe(\n Effect.mapError(() => OAuthRejected.make({})),\n );\n\n const entry = installed.find(\n ({ provider }) => provider.issuance === \"active\" && provider.provider === request.provider,\n );\n\n const provider = entry?.provider;\n\n const callback = provider?.callbacks.find(\n (candidate) => candidate.callbackId === request.callbackId,\n );\n\n if (entry === undefined || provider === undefined || callback === undefined)\n return yield* OAuthRejected.make({});\n\n const result = yield* Effect.tryPromise({\n try: async (signal) => {\n const configuration = privateConfiguration(\n entry,\n timeoutSeconds,\n fetch,\n signal,\n compatibility,\n );\n\n const state = client.randomState();\n const verifier = client.randomPKCECodeVerifier();\n const nonce = provider.protocol === \"oidc\" ? client.randomNonce() : undefined;\n const challenge = await client.calculatePKCECodeChallenge(verifier);\n\n signal.throwIfAborted();\n\n const url = client.buildAuthorizationUrl(\n configuration,\n makeAuthorizationParameters(provider, callback.redirectUri, {\n state,\n challenge,\n ...(nonce === undefined ? {} : { nonce }),\n }),\n );\n\n return {\n configuration: {\n provider: provider.provider,\n protocol: provider.protocol,\n configurationGeneration: provider.configurationGeneration,\n issuer: provider.issuer,\n responseIssuerMode: provider.responseIssuerMode,\n callbackId: callback.callbackId,\n redirectUri: callback.redirectUri,\n },\n authorizationUrl: Redacted.make(url.href),\n secrets: {\n namespace: \"effect-auth/oauth-transaction-secrets/v1\" as const,\n state: Redacted.make(state),\n pkceVerifier: Redacted.make(verifier),\n ...(nonce === undefined ? {} : { oidcNonce: Redacted.make(nonce) }),\n },\n };\n },\n catch: unavailable,\n });\n\n return yield* snapshotOAuth(OAuthProtocolPreparation, result);\n });\n\n const exchangeVerifiedIdentity: OAuthProtocol[\"Service\"][\"exchangeVerifiedIdentity\"] =\n Effect.fn(\"OpenIdClient.exchangeVerifiedIdentity\")(function* (input) {\n const request = yield* snapshotOAuth(exchangeInput, input);\n const saved = request.configuration;\n\n const entry = installed.find(\n ({ provider }) =>\n provider.provider === saved.provider &&\n provider.configurationGeneration === saved.configurationGeneration,\n );\n\n if (entry === undefined) return yield* unavailable();\n const provider = entry.provider;\n\n const callback = provider.callbacks.find(\n (candidate) => candidate.callbackId === saved.callbackId,\n );\n\n if (\n provider.protocol !== saved.protocol ||\n provider.issuer !== saved.issuer ||\n provider.responseIssuerMode !== saved.responseIssuerMode ||\n callback?.redirectUri !== saved.redirectUri\n )\n return yield* unavailable();\n if (\n (provider.protocol === \"oidc\") !== (request.secrets.oidcNonce !== undefined) ||\n Redacted.value(request.response.state) !== Redacted.value(request.secrets.state) ||\n (provider.responseIssuerMode === \"required\"\n ? request.response.issuer !== provider.issuer\n : request.response.issuer !== undefined)\n )\n return yield* rejected();\n const startedAt = DateTime.toEpochMillis(request.verificationStartedAt);\n\n if (startedAt < 0 || startedAt > DateTime.toEpochMillis(yield* DateTime.now))\n return yield* rejected();\n\n const exchanged = yield* Effect.tryPromise({\n try: async (signal) => {\n const configuration = privateConfiguration(\n entry,\n timeoutSeconds,\n fetch,\n signal,\n compatibility,\n );\n\n const currentUrl = new URL(saved.redirectUri);\n\n currentUrl.searchParams.set(\"code\", Redacted.value(request.response.code));\n currentUrl.searchParams.set(\"state\", Redacted.value(request.response.state));\n if (request.response.issuer !== undefined)\n currentUrl.searchParams.set(\"iss\", request.response.issuer);\n\n const tokens = await client.authorizationCodeGrant(\n configuration,\n currentUrl,\n {\n pkceCodeVerifier: Redacted.value(request.secrets.pkceVerifier),\n expectedState: Redacted.value(request.secrets.state),\n ...(provider.protocol === \"oidc\"\n ? {\n expectedNonce: Redacted.value(request.secrets.oidcNonce!),\n idTokenExpected: true,\n ...(provider.maxAgeSeconds === undefined\n ? {}\n : { maxAge: provider.maxAgeSeconds }),\n }\n : {}),\n },\n provider.tokenParameters,\n );\n\n signal.throwIfAborted();\n if (provider.protocol === \"oidc\")\n return { protocol: \"oidc\" as const, claims: tokens.claims() };\n if (tokens.token_type !== \"bearer\") throw unavailable();\n\n const response = await client.fetchProtectedResource(\n configuration,\n tokens.access_token,\n new URL(provider.identitySource.url),\n \"GET\",\n undefined,\n new Headers(provider.identitySource.headers),\n );\n\n signal.throwIfAborted();\n if (\n response.status !== 200 ||\n response.headers.get(\"content-type\")?.split(\";\", 1)[0]?.trim().toLowerCase() !==\n \"application/json\"\n )\n throw unavailable();\n const body: unknown = await response.json();\n\n signal.throwIfAborted();\n\n return { protocol: \"oauth\" as const, body };\n },\n catch: grantError,\n });\n\n if (exchanged.protocol === \"oidc\") {\n // oxlint-disable-next-line no-restricted-properties -- Project validated foreign ID-token claims into the adapter's stricter bounded profile.\n const claims = yield* Schema.decodeUnknownEffect(claimsSchema)(exchanged.claims).pipe(\n Effect.mapError(rejected),\n );\n\n const now = DateTime.toEpochMillis(yield* DateTime.now) / 1000;\n const audience = typeof claims.aud === \"string\" ? claims.aud : claims.aud[0];\n\n if (\n provider.protocol !== \"oidc\" ||\n claims.iss !== provider.issuer ||\n audience !== provider.clientId ||\n (claims.azp !== undefined && claims.azp !== provider.clientId) ||\n claims.exp <= now ||\n claims.iat > now ||\n (claims.nbf !== undefined && claims.nbf > now) ||\n (claims.auth_time !== undefined && claims.auth_time > now) ||\n (provider.maxAgeSeconds !== undefined &&\n (claims.auth_time === undefined ||\n claims.auth_time + provider.maxAgeSeconds < Math.floor(now)))\n )\n return yield* rejected();\n\n return yield* snapshotOAuth(OAuthVerifiedExternalIdentity, {\n identity: { provider: provider.provider, issuer: provider.issuer, subject: claims.sub },\n ...(claims.auth_time === undefined\n ? {}\n : {\n upstreamAuthenticatedAt: DateTime.makeUnsafe(\n Math.min(startedAt, claims.auth_time * 1000),\n ),\n }),\n });\n }\n if (provider.protocol !== \"oauth\") return yield* unavailable();\n\n const decoded = yield* Effect.suspend(() =>\n provider.identitySource.decodeIdentity(exchanged.body),\n ).pipe(\n Effect.provideContext(context),\n Effect.catchCause(\n (cause): Effect.Effect<never, OAuthProtocolRejected | OAuthUnavailable> => {\n if (Cause.hasInterrupts(cause))\n return reportAuthFailure(\"oauth-identity\", cause).pipe(\n Effect.andThen(Effect.interrupt),\n );\n if (\n cause.reasons.length === 1 &&\n cause.reasons[0]?._tag === \"Fail\" &&\n Schema.is(OAuthProtocolRejected)(cause.reasons[0].error)\n )\n return Effect.fail(rejected());\n\n return reportAuthFailure(\"oauth-identity\", cause).pipe(\n Effect.andThen(Effect.fail(unavailable())),\n );\n },\n ),\n );\n\n const identity = yield* Schema.decodeEffect(plainIdentitySchema)(decoded).pipe(\n Effect.mapError(rejected),\n );\n\n return yield* snapshotOAuth(OAuthVerifiedExternalIdentity, {\n identity: {\n provider: provider.provider,\n issuer: provider.issuer,\n subject: identity.subject,\n },\n ...(identity.profile === undefined ? {} : { profile: identity.profile }),\n });\n });\n\n return OAuthProtocol.of({\n prepareAuthorization: (input) => unavailableOnDefect(prepareAuthorization(input)),\n exchangeVerifiedIdentity: (input) => unavailableOnDefect(exchangeVerifiedIdentity(input)),\n });\n },\n unavailableOnDefect,\n);\n\nexport const makeOpenIdClientOAuthProtocol = <R = never>(\n options: OpenIdClientOAuthProtocolOptions<R>,\n) => makeOAuthProtocolWithCompatibility(options);\n\nexport const openIdClientOAuthProtocolLayer = <R = never>(\n options: OpenIdClientOAuthProtocolOptions<R>,\n) => Layer.effect(OAuthProtocol, makeOpenIdClientOAuthProtocol(options));\n"],"mappings":"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"}
1
+ {"version":3,"file":"protocol.mjs","names":[],"sources":["../../../src/oauth/openid-client/protocol.ts"],"sourcesContent":["import { Cause, DateTime, Effect, Layer, Redacted, Schema } from \"effect\";\nimport * as client from \"openid-client\";\n\nimport { reportAuthFailure } from \"../../internal/diagnostics\";\nimport { RequestBindingFlowId } from \"../../operations/requestBinding\";\nimport { OAuthProtocol } from \"../OAuthProtocol\";\nimport { OAuthProviderKey } from \"../schema\";\nimport { OAuthProtocolRejected, OAuthRejected, OAuthUnavailable } from \"../signInErrors\";\nimport {\n OAuthCallbackId,\n OAuthCodeResponse,\n OAuthDisplayProfile,\n OAuthProtocolConfiguration,\n OAuthProtocolPreparation,\n OAuthTransactionSecrets,\n OAuthVerifiedExternalIdentity,\n} from \"../signInModels\";\nimport { snapshotOAuth } from \"../signInSnapshot\";\nimport { DefiniteTokenRejection, tokenCompatibility } from \"./compatibility\";\nimport {\n clientAuthentication,\n installConfigurations,\n makeAuthorizationParameters,\n type InstalledProvider,\n} from \"./configuration\";\nimport {\n type OpenIdClientConfigurationError,\n type OpenIdClientOAuthProtocolOptions,\n} from \"./models\";\nimport { boundedFetch } from \"./transport\";\n\nconst beginInput = Schema.Struct({\n provider: OAuthProviderKey,\n callbackId: OAuthCallbackId,\n flowId: RequestBindingFlowId,\n});\n\nconst exchangeInput = Schema.toType(\n Schema.Struct({\n configuration: OAuthProtocolConfiguration,\n response: OAuthCodeResponse,\n secrets: OAuthTransactionSecrets,\n verificationStartedAt: Schema.DateTimeUtcFromMillis,\n }),\n);\n\nconst numericDate = Schema.Finite.check(Schema.isBetween({ minimum: 0, maximum: 8640000000000 }));\n\nconst claimsSchema = Schema.Struct({\n iss: Schema.String,\n sub: OAuthVerifiedExternalIdentity.fields.identity.fields.subject,\n aud: Schema.Union([\n Schema.String,\n Schema.Array(Schema.String).check(Schema.isMinLength(1), Schema.isMaxLength(1)),\n ]),\n azp: Schema.optionalKey(Schema.String),\n exp: numericDate,\n iat: numericDate,\n nbf: Schema.optionalKey(numericDate),\n auth_time: Schema.optionalKey(numericDate),\n});\n\nconst plainIdentitySchema = Schema.Struct({\n subject: OAuthVerifiedExternalIdentity.fields.identity.fields.subject,\n profile: Schema.optionalKey(OAuthDisplayProfile),\n});\n\nconst unavailable = () => OAuthUnavailable.make({});\nconst rejected = () => OAuthProtocolRejected.make({});\n\nconst unavailableOnDefect = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n effect.pipe(\n Effect.tapCause((cause) =>\n Cause.hasDies(cause) ? reportAuthFailure(\"oauth-protocol\", cause) : Effect.void,\n ),\n Effect.catchCause((cause): Effect.Effect<never, E | OAuthUnavailable> => {\n if (Cause.hasInterrupts(cause)) return Effect.interrupt;\n if (Cause.hasDies(cause)) return Effect.fail(unavailable());\n\n return Effect.failCause(cause);\n }),\n );\n\n/** Only precise claim errors and a fully parsed invalid_grant are definite.\n * INVALID_RESPONSE also covers signature/key/transport faults; keep it ambiguous. */\nconst grantError = (error: unknown) => {\n if (\n error instanceof DefiniteTokenRejection ||\n (error instanceof client.ClientError && error.cause instanceof DefiniteTokenRejection)\n )\n return rejected();\n if (\n error instanceof client.ClientError &&\n (error.code === \"OAUTH_JWT_CLAIM_COMPARISON_FAILED\" ||\n error.code === \"OAUTH_JWT_TIMESTAMP_CHECK_FAILED\")\n )\n return rejected();\n if (\n error instanceof client.ResponseBodyError &&\n error.status === 400 &&\n error.error === \"invalid_grant\"\n )\n return rejected();\n\n return unavailable();\n};\n\nconst privateConfiguration = <R>(\n entry: InstalledProvider<R>,\n timeout: number,\n fetch: client.CustomFetch,\n signal: AbortSignal,\n) => {\n const provider = entry.provider;\n const compatibility = provider.protocol === \"oauth\" ? provider[tokenCompatibility] : undefined;\n\n const configuration = new client.Configuration(\n entry.metadata,\n provider.clientId,\n {\n [client.clockSkew]: 0,\n [client.clockTolerance]: 0,\n ...(provider.protocol === \"oidc\"\n ? { id_token_signed_response_alg: provider.idTokenSignedResponseAlg }\n : {}),\n },\n clientAuthentication(provider.authentication),\n );\n\n configuration.timeout = timeout;\n const transport = boundedFetch(fetch, signal, entry.allowedUrls);\n\n configuration[client.customFetch] =\n compatibility === undefined\n ? transport\n : async (url, options) => {\n const response = await transport(url, options);\n\n if (url === new URL(entry.metadata.token_endpoint!).href) {\n const body: unknown = await response.clone().json();\n\n signal.throwIfAborted();\n compatibility.inspectReceipt(\n { body, status: response.status, contentType: response.headers.get(\"content-type\") },\n {\n scopes: provider.scopes,\n refreshRequired: false,\n operation: \"authorization_code\",\n },\n );\n signal.throwIfAborted();\n }\n\n return response;\n };\n if (provider.protocol === \"oidc\") client.enableNonRepudiationChecks(configuration);\n\n return configuration;\n};\n\nexport const makeOpenIdClientOAuthProtocol = Effect.fn(\"makeOpenIdClientOAuthProtocol\")(\n // Capture one provider table; each generation retains its own receipt rules.\n function* <R = never>(\n options: OpenIdClientOAuthProtocolOptions<R>,\n ): Effect.fn.Return<\n OAuthProtocol[\"Service\"],\n OpenIdClientConfigurationError | OAuthUnavailable,\n R\n > {\n const context = yield* Effect.context<R>();\n const { installed, fetch, timeoutSeconds } = yield* installConfigurations(options);\n\n const prepareAuthorization: OAuthProtocol[\"Service\"][\"prepareAuthorization\"] = Effect.fn(\n \"OpenIdClient.prepareAuthorization\",\n )(function* (input) {\n const request = yield* Schema.decodeEffect(beginInput)(input).pipe(\n Effect.mapError(() => OAuthRejected.make({})),\n );\n\n const entry = installed.find(\n ({ provider }) => provider.issuance === \"active\" && provider.provider === request.provider,\n );\n\n const provider = entry?.provider;\n\n const callback = provider?.callbacks.find(\n (candidate) => candidate.callbackId === request.callbackId,\n );\n\n if (entry === undefined || provider === undefined || callback === undefined)\n return yield* OAuthRejected.make({});\n\n const result = yield* Effect.tryPromise({\n try: async (signal) => {\n const configuration = privateConfiguration(entry, timeoutSeconds, fetch, signal);\n\n const state = client.randomState();\n const verifier = client.randomPKCECodeVerifier();\n const nonce = provider.protocol === \"oidc\" ? client.randomNonce() : undefined;\n const challenge = await client.calculatePKCECodeChallenge(verifier);\n\n signal.throwIfAborted();\n\n const url = client.buildAuthorizationUrl(\n configuration,\n makeAuthorizationParameters(provider, callback.redirectUri, {\n state,\n challenge,\n ...(nonce === undefined ? {} : { nonce }),\n }),\n );\n\n return {\n configuration: {\n provider: provider.provider,\n protocol: provider.protocol,\n configurationGeneration: provider.configurationGeneration,\n issuer: provider.issuer,\n responseIssuerMode: provider.responseIssuerMode,\n callbackId: callback.callbackId,\n redirectUri: callback.redirectUri,\n },\n authorizationUrl: Redacted.make(url.href),\n secrets: {\n namespace: \"effect-auth/oauth-transaction-secrets/v1\" as const,\n state: Redacted.make(state),\n pkceVerifier: Redacted.make(verifier),\n ...(nonce === undefined ? {} : { oidcNonce: Redacted.make(nonce) }),\n },\n };\n },\n catch: unavailable,\n });\n\n return yield* snapshotOAuth(OAuthProtocolPreparation, result);\n });\n\n const exchangeVerifiedIdentity: OAuthProtocol[\"Service\"][\"exchangeVerifiedIdentity\"] =\n Effect.fn(\"OpenIdClient.exchangeVerifiedIdentity\")(function* (input) {\n const request = yield* snapshotOAuth(exchangeInput, input);\n const saved = request.configuration;\n\n const entry = installed.find(\n ({ provider }) =>\n provider.provider === saved.provider &&\n provider.configurationGeneration === saved.configurationGeneration,\n );\n\n if (entry === undefined) return yield* unavailable();\n const provider = entry.provider;\n\n const callback = provider.callbacks.find(\n (candidate) => candidate.callbackId === saved.callbackId,\n );\n\n if (\n provider.protocol !== saved.protocol ||\n provider.issuer !== saved.issuer ||\n provider.responseIssuerMode !== saved.responseIssuerMode ||\n callback?.redirectUri !== saved.redirectUri\n )\n return yield* unavailable();\n if (\n (provider.protocol === \"oidc\") !== (request.secrets.oidcNonce !== undefined) ||\n Redacted.value(request.response.state) !== Redacted.value(request.secrets.state) ||\n (provider.responseIssuerMode === \"required\"\n ? request.response.issuer !== provider.issuer\n : request.response.issuer !== undefined)\n )\n return yield* rejected();\n const startedAt = DateTime.toEpochMillis(request.verificationStartedAt);\n\n if (startedAt < 0 || startedAt > DateTime.toEpochMillis(yield* DateTime.now))\n return yield* rejected();\n\n const exchanged = yield* Effect.tryPromise({\n try: async (signal) => {\n const configuration = privateConfiguration(entry, timeoutSeconds, fetch, signal);\n\n const currentUrl = new URL(saved.redirectUri);\n\n currentUrl.searchParams.set(\"code\", Redacted.value(request.response.code));\n currentUrl.searchParams.set(\"state\", Redacted.value(request.response.state));\n if (request.response.issuer !== undefined)\n currentUrl.searchParams.set(\"iss\", request.response.issuer);\n\n const tokens = await client.authorizationCodeGrant(\n configuration,\n currentUrl,\n {\n pkceCodeVerifier: Redacted.value(request.secrets.pkceVerifier),\n expectedState: Redacted.value(request.secrets.state),\n ...(provider.protocol === \"oidc\"\n ? {\n expectedNonce: Redacted.value(request.secrets.oidcNonce!),\n idTokenExpected: true,\n ...(provider.maxAgeSeconds === undefined\n ? {}\n : { maxAge: provider.maxAgeSeconds }),\n }\n : {}),\n },\n provider.tokenParameters,\n );\n\n signal.throwIfAborted();\n if (provider.protocol === \"oidc\")\n return { protocol: \"oidc\" as const, claims: tokens.claims() };\n if (tokens.token_type !== \"bearer\") throw unavailable();\n\n const response = await client.fetchProtectedResource(\n configuration,\n tokens.access_token,\n new URL(provider.identitySource.url),\n \"GET\",\n undefined,\n new Headers(provider.identitySource.headers),\n );\n\n signal.throwIfAborted();\n if (\n response.status !== 200 ||\n response.headers.get(\"content-type\")?.split(\";\", 1)[0]?.trim().toLowerCase() !==\n \"application/json\"\n )\n throw unavailable();\n const body: unknown = await response.json();\n\n signal.throwIfAborted();\n\n return { protocol: \"oauth\" as const, body };\n },\n catch: grantError,\n });\n\n if (exchanged.protocol === \"oidc\") {\n // oxlint-disable-next-line no-restricted-properties -- Project validated foreign ID-token claims into the adapter's stricter bounded profile.\n const claims = yield* Schema.decodeUnknownEffect(claimsSchema)(exchanged.claims).pipe(\n Effect.mapError(rejected),\n );\n\n const now = DateTime.toEpochMillis(yield* DateTime.now) / 1000;\n const audience = typeof claims.aud === \"string\" ? claims.aud : claims.aud[0];\n\n if (\n provider.protocol !== \"oidc\" ||\n claims.iss !== provider.issuer ||\n audience !== provider.clientId ||\n (claims.azp !== undefined && claims.azp !== provider.clientId) ||\n claims.exp <= now ||\n claims.iat > now ||\n (claims.nbf !== undefined && claims.nbf > now) ||\n (claims.auth_time !== undefined && claims.auth_time > now) ||\n (provider.maxAgeSeconds !== undefined &&\n (claims.auth_time === undefined ||\n claims.auth_time + provider.maxAgeSeconds < Math.floor(now)))\n )\n return yield* rejected();\n\n return yield* snapshotOAuth(OAuthVerifiedExternalIdentity, {\n identity: { provider: provider.provider, issuer: provider.issuer, subject: claims.sub },\n ...(claims.auth_time === undefined\n ? {}\n : {\n upstreamAuthenticatedAt: DateTime.makeUnsafe(\n Math.min(startedAt, claims.auth_time * 1000),\n ),\n }),\n });\n }\n if (provider.protocol !== \"oauth\") return yield* unavailable();\n\n const decoded = yield* Effect.suspend(() =>\n provider.identitySource.decodeIdentity(exchanged.body),\n ).pipe(\n Effect.provideContext(context),\n Effect.catchCause(\n (cause): Effect.Effect<never, OAuthProtocolRejected | OAuthUnavailable> => {\n if (Cause.hasInterrupts(cause))\n return reportAuthFailure(\"oauth-identity\", cause).pipe(\n Effect.andThen(Effect.interrupt),\n );\n if (\n cause.reasons.length === 1 &&\n cause.reasons[0]?._tag === \"Fail\" &&\n Schema.is(OAuthProtocolRejected)(cause.reasons[0].error)\n )\n return Effect.fail(rejected());\n\n return reportAuthFailure(\"oauth-identity\", cause).pipe(\n Effect.andThen(Effect.fail(unavailable())),\n );\n },\n ),\n );\n\n const identity = yield* Schema.decodeEffect(plainIdentitySchema)(decoded).pipe(\n Effect.mapError(rejected),\n );\n\n return yield* snapshotOAuth(OAuthVerifiedExternalIdentity, {\n identity: {\n provider: provider.provider,\n issuer: provider.issuer,\n subject: identity.subject,\n },\n ...(identity.profile === undefined ? {} : { profile: identity.profile }),\n });\n });\n\n return OAuthProtocol.of({\n prepareAuthorization: (input) => unavailableOnDefect(prepareAuthorization(input)),\n exchangeVerifiedIdentity: (input) => unavailableOnDefect(exchangeVerifiedIdentity(input)),\n });\n },\n unavailableOnDefect,\n);\n\nexport const openIdClientOAuthProtocolLayer = <R = never>(\n options: OpenIdClientOAuthProtocolOptions<R>,\n) => Layer.effect(OAuthProtocol, makeOpenIdClientOAuthProtocol(options));\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@yielded/auth","version":"0.1.0-beta.1","dependencies":{"@noble/ciphers":"2.1.1","@noble/hashes":"2.3.0"},"devDependencies":{"@cloudflare/workers-types":"5.20260825.1","@effect/platform-bun":"4.0.0-rc.112","@effect/platform-node":"4.0.0-rc.112","@effect/sql-d1":"4.0.0-rc.112","@effect/sql-libsql":"4.0.0-rc.112","@effect/sql-mysql2":"4.0.0-rc.112","@effect/sql-pg":"4.0.0-rc.112","@effect/sql-pglite":"4.0.0-rc.112","@effect/sql-sqlite-bun":"4.0.0-rc.112","@effect/sql-sqlite-do":"4.0.0-rc.112","@effect/sql-sqlite-node":"4.0.0-rc.112","@effect/sql-sqlite-wasm":"4.0.0-rc.112","@effect/vitest":"4.0.0-rc.112","@simplewebauthn/browser":"14.0.0","@simplewebauthn/server":"14.0.1","drizzle-orm":"1.0.0-rc.5-ab785fc","effect":"4.0.0-rc.112","effect-cf":"0.40.0","openid-client":"6.8.8","tldts":"7.4.11","typescript":"7.0.2","vite-plus":"0.3.0"},"peerDependencies":{"@effect/sql-d1":">=4.0.0-rc.112","@effect/sql-libsql":">=4.0.0-rc.112","@effect/sql-mysql2":">=4.0.0-rc.112","@effect/sql-pg":">=4.0.0-rc.112","@effect/sql-pglite":">=4.0.0-rc.112","@effect/sql-sqlite-bun":">=4.0.0-rc.112","@effect/sql-sqlite-do":">=4.0.0-rc.112","@effect/sql-sqlite-node":">=4.0.0-rc.112","@effect/sql-sqlite-wasm":">=4.0.0-rc.112","@simplewebauthn/browser":">=14.0.0 <15","@simplewebauthn/server":">=14.0.1 <15","drizzle-orm":">=1.0.0-rc.5-ab785fc","effect":"^4.0.0-rc.112","effect-cf":"^0.40.0","openid-client":">=6.8.8 <7","tldts":">=7.4.11 <8"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./Auth":{"types":"./dist/Auth.d.mts","default":"./dist/Auth.mjs"},"./Drizzle":{"types":"./dist/Drizzle.d.mts","default":"./dist/Drizzle.mjs"},"./DrizzleD1":{"types":"./dist/DrizzleD1.d.mts","default":"./dist/DrizzleD1.mjs"},"./DrizzleLibsql":{"types":"./dist/DrizzleLibsql.d.mts","default":"./dist/DrizzleLibsql.mjs"},"./DrizzleMysql2":{"types":"./dist/DrizzleMysql2.d.mts","default":"./dist/DrizzleMysql2.mjs"},"./DrizzlePglite":{"types":"./dist/DrizzlePglite.d.mts","default":"./dist/DrizzlePglite.mjs"},"./DrizzlePostgres":{"types":"./dist/DrizzlePostgres.d.mts","default":"./dist/DrizzlePostgres.mjs"},"./DrizzleSqliteBun":{"types":"./dist/DrizzleSqliteBun.d.mts","default":"./dist/DrizzleSqliteBun.mjs"},"./DrizzleSqliteDo":{"types":"./dist/DrizzleSqliteDo.d.mts","default":"./dist/DrizzleSqliteDo.mjs"},"./DrizzleSqliteNode":{"types":"./dist/DrizzleSqliteNode.d.mts","default":"./dist/DrizzleSqliteNode.mjs"},"./DrizzleSqliteWasm":{"types":"./dist/DrizzleSqliteWasm.d.mts","default":"./dist/DrizzleSqliteWasm.mjs"},"./Cloudflare":{"types":"./dist/Cloudflare.d.mts","default":"./dist/Cloudflare.mjs"},"./Http":{"types":"./dist/Http.d.mts","default":"./dist/Http.mjs"},"./HttpServer":{"types":"./dist/HttpServer.d.mts","default":"./dist/HttpServer.mjs"},"./OperationHttp":{"types":"./dist/OperationHttp.d.mts","default":"./dist/OperationHttp.mjs"},"./OperationHttpClient":{"types":"./dist/OperationHttpClient.d.mts","default":"./dist/OperationHttpClient.mjs"},"./OperationHttpServer":{"types":"./dist/OperationHttpServer.d.mts","default":"./dist/OperationHttpServer.mjs"},"./Atom":{"types":"./dist/Atom.d.mts","default":"./dist/Atom.mjs"},"./Hooks":{"types":"./dist/Hooks.d.mts","default":"./dist/Hooks.mjs"},"./Identity":{"types":"./dist/Identity.d.mts","default":"./dist/Identity.mjs"},"./OAuth":{"types":"./dist/OAuth.d.mts","default":"./dist/OAuth.mjs"},"./Operations":{"types":"./dist/Operations.d.mts","default":"./dist/Operations.mjs"},"./Rpc":{"types":"./dist/Rpc.d.mts","default":"./dist/Rpc.mjs"},"./Schema":{"types":"./dist/Schema.d.mts","default":"./dist/Schema.mjs"},"./Testing":{"types":"./dist/Testing.d.mts","default":"./dist/Testing.mjs"},"./WebCrypto":{"types":"./dist/WebCrypto.d.mts","default":"./dist/WebCrypto.mjs"},"./Sessions":{"types":"./dist/Sessions.d.mts","default":"./dist/Sessions.mjs"},"./SessionContract":{"types":"./dist/SessionContract.d.mts","default":"./dist/SessionContract.mjs"},"./Proofs":{"types":"./dist/Proofs.d.mts","default":"./dist/Proofs.mjs"},"./Password":{"types":"./dist/Password.d.mts","default":"./dist/Password.mjs"},"./Email":{"types":"./dist/Email.d.mts","default":"./dist/Email.mjs"},"./OpenIdClient":{"types":"./dist/OpenIdClient.d.mts","default":"./dist/OpenIdClient.mjs"},"./OpenIdClientConnected":{"types":"./dist/OpenIdClientConnected.d.mts","default":"./dist/OpenIdClientConnected.mjs"},"./Passkey":{"types":"./dist/Passkey.d.mts","default":"./dist/Passkey.mjs"},"./PasskeyPassword":{"types":"./dist/PasskeyPassword.d.mts","default":"./dist/PasskeyPassword.mjs"},"./PasskeySimpleWebAuthn":{"types":"./dist/PasskeySimpleWebAuthn.d.mts","default":"./dist/PasskeySimpleWebAuthn.mjs"},"./PasskeyBrowser":{"types":"./dist/PasskeyBrowser.d.mts","default":"./dist/PasskeyBrowser.mjs"},"./GitHub":{"types":"./dist/GitHub.d.mts","default":"./dist/GitHub.mjs"},"./AuthSession":{"types":"./dist/AuthSession.d.mts","default":"./dist/AuthSession.mjs"},"./Errors":{"types":"./dist/Errors.d.mts","default":"./dist/Errors.mjs"},"./Workflows":{"types":"./dist/Workflows.d.mts","default":"./dist/Workflows.mjs"},"./PasswordHasher":{"types":"./dist/PasswordHasher.d.mts","default":"./dist/PasswordHasher.mjs"},"./EmailOtp":{"types":"./dist/EmailOtp.d.mts","default":"./dist/EmailOtp.mjs"},"./AuthStore":{"types":"./dist/AuthStore.d.mts","default":"./dist/AuthStore.mjs"},"./PasswordAuth":{"types":"./dist/PasswordAuth.d.mts","default":"./dist/PasswordAuth.mjs"},"./Policy":{"types":"./dist/Policy.d.mts","default":"./dist/Policy.mjs"},"./EmailOtpSender":{"types":"./dist/EmailOtpSender.d.mts","default":"./dist/EmailOtpSender.mjs"},"./AuthTokenCodec":{"types":"./dist/AuthTokenCodec.d.mts","default":"./dist/AuthTokenCodec.mjs"},"./IdentityResolver":{"types":"./dist/IdentityResolver.d.mts","default":"./dist/IdentityResolver.mjs"},"./PasswordCredentialStore":{"types":"./dist/PasswordCredentialStore.d.mts","default":"./dist/PasswordCredentialStore.mjs"},"./PhoneOtp":{"types":"./dist/PhoneOtp.d.mts","default":"./dist/PhoneOtp.mjs"},"./Totp":{"types":"./dist/Totp.d.mts","default":"./dist/Totp.mjs"},"./PasskeyContract":{"types":"./dist/PasskeyContract.d.mts","default":"./dist/PasskeyContract.mjs"},"./TotpContract":{"types":"./dist/TotpContract.d.mts","default":"./dist/TotpContract.mjs"},"./AuthContract":{"types":"./dist/AuthContract.d.mts","default":"./dist/AuthContract.mjs"},"./Client":{"types":"./dist/Client.d.mts","default":"./dist/Client.mjs"}},"description":"Composable authentication, sessions, and identity workflows for Effect.","keywords":["authentication","effect","oauth","passkeys","sessions","typescript"],"homepage":"https://github.com/danieljvdm/effect-auth#readme","bugs":{"url":"https://github.com/danieljvdm/effect-auth/issues"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-auth.git","directory":"packages/effect-auth"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests","e2e":"bun test/e2e/harness.ts","example:totp":"bun test/fixtures/totp-sqlite-bun.ts"},"peerDependenciesMeta":{"@effect/sql-d1":{"optional":true},"@effect/sql-libsql":{"optional":true},"@effect/sql-mysql2":{"optional":true},"@effect/sql-pg":{"optional":true},"@effect/sql-pglite":{"optional":true},"@effect/sql-sqlite-bun":{"optional":true},"@effect/sql-sqlite-do":{"optional":true},"@effect/sql-sqlite-node":{"optional":true},"@effect/sql-sqlite-wasm":{"optional":true},"@simplewebauthn/browser":{"optional":true},"@simplewebauthn/server":{"optional":true},"drizzle-orm":{"optional":true},"effect-cf":{"optional":true},"openid-client":{"optional":true},"tldts":{"optional":true}}}
1
+ {"name":"@yielded/auth","version":"0.1.0-beta.3","dependencies":{"@noble/ciphers":"2.1.1","@noble/hashes":"2.3.0"},"devDependencies":{"@cloudflare/workers-types":"5.20260825.1","@effect/platform-bun":"4.0.0-rc.112","@effect/platform-node":"4.0.0-rc.112","@effect/sql-d1":"4.0.0-rc.112","@effect/sql-libsql":"4.0.0-rc.112","@effect/sql-mysql2":"4.0.0-rc.112","@effect/sql-pg":"4.0.0-rc.112","@effect/sql-pglite":"4.0.0-rc.112","@effect/sql-sqlite-bun":"4.0.0-rc.112","@effect/sql-sqlite-do":"4.0.0-rc.112","@effect/sql-sqlite-node":"4.0.0-rc.112","@effect/sql-sqlite-wasm":"4.0.0-rc.112","@effect/vitest":"4.0.0-rc.112","@simplewebauthn/browser":"14.0.0","@simplewebauthn/server":"14.0.1","drizzle-orm":"1.0.0-rc.5-ab785fc","effect":"4.0.0-rc.112","effect-cf":"0.40.0","openid-client":"6.8.8","tldts":"7.4.11","typescript":"7.0.2","vite-plus":"0.3.0"},"peerDependencies":{"@effect/sql-d1":">=4.0.0-rc.112","@effect/sql-libsql":">=4.0.0-rc.112","@effect/sql-mysql2":">=4.0.0-rc.112","@effect/sql-pg":">=4.0.0-rc.112","@effect/sql-pglite":">=4.0.0-rc.112","@effect/sql-sqlite-bun":">=4.0.0-rc.112","@effect/sql-sqlite-do":">=4.0.0-rc.112","@effect/sql-sqlite-node":">=4.0.0-rc.112","@effect/sql-sqlite-wasm":">=4.0.0-rc.112","@simplewebauthn/browser":">=14.0.0 <15","@simplewebauthn/server":">=14.0.1 <15","drizzle-orm":">=1.0.0-rc.5-ab785fc","effect":"^4.0.0-rc.112","effect-cf":"^0.40.0","openid-client":">=6.8.8 <7","tldts":">=7.4.11 <8"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./Auth":{"types":"./dist/Auth.d.mts","default":"./dist/Auth.mjs"},"./Drizzle":{"types":"./dist/Drizzle.d.mts","default":"./dist/Drizzle.mjs"},"./DrizzleD1":{"types":"./dist/DrizzleD1.d.mts","default":"./dist/DrizzleD1.mjs"},"./DrizzleLibsql":{"types":"./dist/DrizzleLibsql.d.mts","default":"./dist/DrizzleLibsql.mjs"},"./DrizzleMysql2":{"types":"./dist/DrizzleMysql2.d.mts","default":"./dist/DrizzleMysql2.mjs"},"./DrizzlePglite":{"types":"./dist/DrizzlePglite.d.mts","default":"./dist/DrizzlePglite.mjs"},"./DrizzlePostgres":{"types":"./dist/DrizzlePostgres.d.mts","default":"./dist/DrizzlePostgres.mjs"},"./DrizzleSqliteBun":{"types":"./dist/DrizzleSqliteBun.d.mts","default":"./dist/DrizzleSqliteBun.mjs"},"./DrizzleSqliteDo":{"types":"./dist/DrizzleSqliteDo.d.mts","default":"./dist/DrizzleSqliteDo.mjs"},"./DrizzleSqliteNode":{"types":"./dist/DrizzleSqliteNode.d.mts","default":"./dist/DrizzleSqliteNode.mjs"},"./DrizzleSqliteWasm":{"types":"./dist/DrizzleSqliteWasm.d.mts","default":"./dist/DrizzleSqliteWasm.mjs"},"./Cloudflare":{"types":"./dist/Cloudflare.d.mts","default":"./dist/Cloudflare.mjs"},"./Http":{"types":"./dist/Http.d.mts","default":"./dist/Http.mjs"},"./HttpServer":{"types":"./dist/HttpServer.d.mts","default":"./dist/HttpServer.mjs"},"./OperationHttp":{"types":"./dist/OperationHttp.d.mts","default":"./dist/OperationHttp.mjs"},"./OperationHttpClient":{"types":"./dist/OperationHttpClient.d.mts","default":"./dist/OperationHttpClient.mjs"},"./OperationHttpServer":{"types":"./dist/OperationHttpServer.d.mts","default":"./dist/OperationHttpServer.mjs"},"./Atom":{"types":"./dist/Atom.d.mts","default":"./dist/Atom.mjs"},"./Hooks":{"types":"./dist/Hooks.d.mts","default":"./dist/Hooks.mjs"},"./Identity":{"types":"./dist/Identity.d.mts","default":"./dist/Identity.mjs"},"./OAuth":{"types":"./dist/OAuth.d.mts","default":"./dist/OAuth.mjs"},"./Operations":{"types":"./dist/Operations.d.mts","default":"./dist/Operations.mjs"},"./Rpc":{"types":"./dist/Rpc.d.mts","default":"./dist/Rpc.mjs"},"./Schema":{"types":"./dist/Schema.d.mts","default":"./dist/Schema.mjs"},"./Testing":{"types":"./dist/Testing.d.mts","default":"./dist/Testing.mjs"},"./WebCrypto":{"types":"./dist/WebCrypto.d.mts","default":"./dist/WebCrypto.mjs"},"./Sessions":{"types":"./dist/Sessions.d.mts","default":"./dist/Sessions.mjs"},"./SessionContract":{"types":"./dist/SessionContract.d.mts","default":"./dist/SessionContract.mjs"},"./Proofs":{"types":"./dist/Proofs.d.mts","default":"./dist/Proofs.mjs"},"./Password":{"types":"./dist/Password.d.mts","default":"./dist/Password.mjs"},"./Email":{"types":"./dist/Email.d.mts","default":"./dist/Email.mjs"},"./OpenIdClient":{"types":"./dist/OpenIdClient.d.mts","default":"./dist/OpenIdClient.mjs"},"./OpenIdClientConnected":{"types":"./dist/OpenIdClientConnected.d.mts","default":"./dist/OpenIdClientConnected.mjs"},"./Passkey":{"types":"./dist/Passkey.d.mts","default":"./dist/Passkey.mjs"},"./PasskeyPassword":{"types":"./dist/PasskeyPassword.d.mts","default":"./dist/PasskeyPassword.mjs"},"./PasskeySimpleWebAuthn":{"types":"./dist/PasskeySimpleWebAuthn.d.mts","default":"./dist/PasskeySimpleWebAuthn.mjs"},"./PasskeyBrowser":{"types":"./dist/PasskeyBrowser.d.mts","default":"./dist/PasskeyBrowser.mjs"},"./GitHub":{"types":"./dist/GitHub.d.mts","default":"./dist/GitHub.mjs"},"./AuthSession":{"types":"./dist/AuthSession.d.mts","default":"./dist/AuthSession.mjs"},"./Errors":{"types":"./dist/Errors.d.mts","default":"./dist/Errors.mjs"},"./Workflows":{"types":"./dist/Workflows.d.mts","default":"./dist/Workflows.mjs"},"./PasswordHasher":{"types":"./dist/PasswordHasher.d.mts","default":"./dist/PasswordHasher.mjs"},"./EmailOtp":{"types":"./dist/EmailOtp.d.mts","default":"./dist/EmailOtp.mjs"},"./AuthStore":{"types":"./dist/AuthStore.d.mts","default":"./dist/AuthStore.mjs"},"./PasswordAuth":{"types":"./dist/PasswordAuth.d.mts","default":"./dist/PasswordAuth.mjs"},"./Policy":{"types":"./dist/Policy.d.mts","default":"./dist/Policy.mjs"},"./EmailOtpSender":{"types":"./dist/EmailOtpSender.d.mts","default":"./dist/EmailOtpSender.mjs"},"./AuthTokenCodec":{"types":"./dist/AuthTokenCodec.d.mts","default":"./dist/AuthTokenCodec.mjs"},"./IdentityResolver":{"types":"./dist/IdentityResolver.d.mts","default":"./dist/IdentityResolver.mjs"},"./PasswordCredentialStore":{"types":"./dist/PasswordCredentialStore.d.mts","default":"./dist/PasswordCredentialStore.mjs"},"./PhoneOtp":{"types":"./dist/PhoneOtp.d.mts","default":"./dist/PhoneOtp.mjs"},"./Totp":{"types":"./dist/Totp.d.mts","default":"./dist/Totp.mjs"},"./PasskeyContract":{"types":"./dist/PasskeyContract.d.mts","default":"./dist/PasskeyContract.mjs"},"./TotpContract":{"types":"./dist/TotpContract.d.mts","default":"./dist/TotpContract.mjs"},"./AuthContract":{"types":"./dist/AuthContract.d.mts","default":"./dist/AuthContract.mjs"},"./Client":{"types":"./dist/Client.d.mts","default":"./dist/Client.mjs"}},"description":"Composable authentication, sessions, and identity workflows for Effect.","keywords":["authentication","effect","oauth","passkeys","sessions","typescript"],"homepage":"https://yielded.dev/auth/","bugs":{"url":"https://github.com/yielded-dev/auth/issues"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/auth.git","directory":"packages/effect-auth"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests","e2e":"bun test/e2e/harness.ts","example:totp":"bun test/fixtures/totp-sqlite-bun.ts"},"peerDependenciesMeta":{"@effect/sql-d1":{"optional":true},"@effect/sql-libsql":{"optional":true},"@effect/sql-mysql2":{"optional":true},"@effect/sql-pg":{"optional":true},"@effect/sql-pglite":{"optional":true},"@effect/sql-sqlite-bun":{"optional":true},"@effect/sql-sqlite-do":{"optional":true},"@effect/sql-sqlite-node":{"optional":true},"@effect/sql-sqlite-wasm":{"optional":true},"@simplewebauthn/browser":{"optional":true},"@simplewebauthn/server":{"optional":true},"drizzle-orm":{"optional":true},"effect-cf":{"optional":true},"openid-client":{"optional":true},"tldts":{"optional":true}}}
package/src/GitHub.ts CHANGED
@@ -9,6 +9,7 @@ export { OpenIdClientConfigurationError } from "./oauth/openid-client/models";
9
9
  export {
10
10
  gitHubOAuthAppConnectedProtocolLayer,
11
11
  gitHubOAuthAppProtocolLayer,
12
+ gitHubOAuthAppProvider,
12
13
  makeGitHubOAuthAppConnectedProtocol,
13
14
  makeGitHubOAuthAppProtocol,
14
15
  } from "./oauth/github/protocol";
@@ -6,6 +6,7 @@ import { OAuthConnectedProtocol } from "../OAuthConnectedProtocol";
6
6
  import { OAuthProtocol } from "../OAuthProtocol";
7
7
  import {
8
8
  DefiniteTokenRejection,
9
+ tokenCompatibility,
9
10
  type ConnectedCompatibility,
10
11
  } from "../openid-client/compatibility";
11
12
  import { makeConnectedProtocolWithCompatibility } from "../openid-client/connected/protocol";
@@ -13,7 +14,7 @@ import {
13
14
  OpenIdClientConfigurationError,
14
15
  type OpenIdClientOAuthProvider,
15
16
  } from "../openid-client/models";
16
- import { makeOAuthProtocolWithCompatibility } from "../openid-client/protocol";
17
+ import { makeOpenIdClientOAuthProtocol } from "../openid-client/protocol";
17
18
  import { ProviderRevocation } from "../openid-client/ProviderRevocation";
18
19
  import { boundedFetch } from "../openid-client/transport";
19
20
  import { OAuthUnavailable } from "../signInErrors";
@@ -265,6 +266,27 @@ const revocationLayer = (
265
266
  );
266
267
  };
267
268
 
269
+ /** A GitHub.com OAuth App generation for the same provider list as generic OIDC.
270
+ * Retains GitHub receipt/error rules and requests read:user, with no repository access.
271
+ * Construction performs no I/O; invalid configuration throws the typed configuration error. */
272
+ export const gitHubOAuthAppProvider = (
273
+ registration: GitHubOAuthAppGeneration,
274
+ ): OpenIdClientOAuthProvider => {
275
+ let saved: GitHubOAuthAppGeneration;
276
+
277
+ try {
278
+ saved = snapshotOAuthSync(generation, registration);
279
+ } catch {
280
+ throw invalid();
281
+ }
282
+
283
+ return {
284
+ ...provider(saved),
285
+ scopes: ["read:user"],
286
+ [tokenCompatibility]: compatibility,
287
+ };
288
+ };
289
+
268
290
  export const makeGitHubOAuthAppProtocol = Effect.fn("makeGitHubOAuthAppProtocol")(function* (
269
291
  options: GitHubOAuthAppProtocolOptions,
270
292
  ) {
@@ -273,13 +295,10 @@ export const makeGitHubOAuthAppProtocol = Effect.fn("makeGitHubOAuthAppProtocol"
273
295
  if (saved.registrations.filter((item) => item.issuance === "active").length !== 1)
274
296
  return yield* invalid();
275
297
 
276
- return yield* makeOAuthProtocolWithCompatibility(
277
- {
278
- ...saved,
279
- providers: saved.registrations.map((item) => ({ ...provider(item), scopes: ["read:user"] })),
280
- },
281
- compatibility,
282
- );
298
+ return yield* makeOpenIdClientOAuthProtocol({
299
+ ...saved,
300
+ providers: saved.registrations.map(gitHubOAuthAppProvider),
301
+ });
283
302
  });
284
303
 
285
304
  export const makeGitHubOAuthAppConnectedProtocol = Effect.fn("makeGitHubOAuthAppConnectedProtocol")(
@@ -1,3 +1,5 @@
1
+ import { Predicate, Schema } from "effect";
2
+
1
3
  import type {
2
4
  OpenIdClientConnectedOAuthProvider,
3
5
  OpenIdClientConnectedProtocolOptions,
@@ -19,6 +21,17 @@ export interface TokenCompatibility {
19
21
  ) => void;
20
22
  }
21
23
 
24
+ /** First-party rules travel with the exact provider generation. The symbol stays
25
+ * private so generic provider options do not expose grant-bearing hooks. */
26
+ export const tokenCompatibility = Symbol("effect-auth/OpenIdClient/tokenCompatibility");
27
+
28
+ export const TokenCompatibility = Schema.declare<TokenCompatibility>(
29
+ (input): input is TokenCompatibility =>
30
+ Predicate.isObject(input) &&
31
+ "inspectReceipt" in input &&
32
+ Predicate.isFunction(input.inspectReceipt),
33
+ );
34
+
22
35
  export class DefiniteTokenRejection extends Error {}
23
36
 
24
37
  export interface ConnectedCompatibility extends TokenCompatibility {
@@ -11,6 +11,7 @@ import {
11
11
  OAuthRedirectUri,
12
12
  } from "../signInModels";
13
13
  import { freezeOAuth } from "../signInSnapshot";
14
+ import { TokenCompatibility, tokenCompatibility } from "./compatibility";
14
15
  import {
15
16
  OpenIdClientConfigurationError,
16
17
  type OpenIdClientAuthentication,
@@ -70,6 +71,7 @@ const optionsSchema = <R>() =>
70
71
  Schema.Struct({
71
72
  ...common,
72
73
  protocol: Schema.Literal("oauth"),
74
+ [tokenCompatibility]: Schema.optionalKey(TokenCompatibility),
73
75
  authorizationEndpoint: boundedString(2048),
74
76
  tokenEndpoint: boundedString(2048),
75
77
  pkceS256: Schema.Literal(true),
@@ -3,6 +3,7 @@ import type { CustomFetch } from "openid-client";
3
3
 
4
4
  import type { OAuthProtocolRejected } from "../signInErrors";
5
5
  import type { OAuthProtocolConfiguration, OAuthVerifiedExternalIdentity } from "../signInModels";
6
+ import type { TokenCompatibility, tokenCompatibility } from "./compatibility";
6
7
 
7
8
  export class OpenIdClientConfigurationError extends Schema.TaggedError<OpenIdClientConfigurationError>()(
8
9
  "OpenIdClientConfigurationError",
@@ -55,6 +56,8 @@ export interface OpenIdClientOidcProvider extends ProviderGeneration {
55
56
  }
56
57
 
57
58
  export interface OpenIdClientOAuthProvider<R = never> extends ProviderGeneration {
59
+ /** @internal First-party provider behavior, retained by the configuration codec. */
60
+ readonly [tokenCompatibility]?: TokenCompatibility;
58
61
  readonly protocol: "oauth";
59
62
  readonly authorizationEndpoint: string;
60
63
  readonly tokenEndpoint: string;
@@ -16,7 +16,7 @@ import {
16
16
  OAuthVerifiedExternalIdentity,
17
17
  } from "../signInModels";
18
18
  import { snapshotOAuth } from "../signInSnapshot";
19
- import { DefiniteTokenRejection, type TokenCompatibility } from "./compatibility";
19
+ import { DefiniteTokenRejection, tokenCompatibility } from "./compatibility";
20
20
  import {
21
21
  clientAuthentication,
22
22
  installConfigurations,
@@ -110,9 +110,9 @@ const privateConfiguration = <R>(
110
110
  timeout: number,
111
111
  fetch: client.CustomFetch,
112
112
  signal: AbortSignal,
113
- compatibility?: TokenCompatibility,
114
113
  ) => {
115
114
  const provider = entry.provider;
115
+ const compatibility = provider.protocol === "oauth" ? provider[tokenCompatibility] : undefined;
116
116
 
117
117
  const configuration = new client.Configuration(
118
118
  entry.metadata,
@@ -158,10 +158,10 @@ const privateConfiguration = <R>(
158
158
  return configuration;
159
159
  };
160
160
 
161
- export const makeOAuthProtocolWithCompatibility = Effect.fn("makeOpenIdClientOAuthProtocol")(
161
+ export const makeOpenIdClientOAuthProtocol = Effect.fn("makeOpenIdClientOAuthProtocol")(
162
+ // Capture one provider table; each generation retains its own receipt rules.
162
163
  function* <R = never>(
163
164
  options: OpenIdClientOAuthProtocolOptions<R>,
164
- compatibility?: TokenCompatibility,
165
165
  ): Effect.fn.Return<
166
166
  OAuthProtocol["Service"],
167
167
  OpenIdClientConfigurationError | OAuthUnavailable,
@@ -192,13 +192,7 @@ export const makeOAuthProtocolWithCompatibility = Effect.fn("makeOpenIdClientOAu
192
192
 
193
193
  const result = yield* Effect.tryPromise({
194
194
  try: async (signal) => {
195
- const configuration = privateConfiguration(
196
- entry,
197
- timeoutSeconds,
198
- fetch,
199
- signal,
200
- compatibility,
201
- );
195
+ const configuration = privateConfiguration(entry, timeoutSeconds, fetch, signal);
202
196
 
203
197
  const state = client.randomState();
204
198
  const verifier = client.randomPKCECodeVerifier();
@@ -281,13 +275,7 @@ export const makeOAuthProtocolWithCompatibility = Effect.fn("makeOpenIdClientOAu
281
275
 
282
276
  const exchanged = yield* Effect.tryPromise({
283
277
  try: async (signal) => {
284
- const configuration = privateConfiguration(
285
- entry,
286
- timeoutSeconds,
287
- fetch,
288
- signal,
289
- compatibility,
290
- );
278
+ const configuration = privateConfiguration(entry, timeoutSeconds, fetch, signal);
291
279
 
292
280
  const currentUrl = new URL(saved.redirectUri);
293
281
 
@@ -428,10 +416,6 @@ export const makeOAuthProtocolWithCompatibility = Effect.fn("makeOpenIdClientOAu
428
416
  unavailableOnDefect,
429
417
  );
430
418
 
431
- export const makeOpenIdClientOAuthProtocol = <R = never>(
432
- options: OpenIdClientOAuthProtocolOptions<R>,
433
- ) => makeOAuthProtocolWithCompatibility(options);
434
-
435
419
  export const openIdClientOAuthProtocolLayer = <R = never>(
436
420
  options: OpenIdClientOAuthProtocolOptions<R>,
437
421
  ) => Layer.effect(OAuthProtocol, makeOpenIdClientOAuthProtocol(options));