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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/DrizzleD1.d.mts +51 -2
  2. package/dist/DrizzleLibsql.d.mts +53 -4
  3. package/dist/DrizzleMysql2.d.mts +53 -4
  4. package/dist/DrizzlePglite.d.mts +53 -4
  5. package/dist/DrizzlePostgres.d.mts +55 -6
  6. package/dist/DrizzleSqliteBun.d.mts +51 -2
  7. package/dist/DrizzleSqliteDo.d.mts +53 -4
  8. package/dist/DrizzleSqliteNode.d.mts +53 -4
  9. package/dist/DrizzleSqliteWasm.d.mts +55 -6
  10. package/dist/GitHub.d.mts +2 -1
  11. package/dist/GitHub.mjs +2 -1
  12. package/dist/OpenIdClient.d.mts +2 -1
  13. package/dist/OpenIdClient.mjs +2 -1
  14. package/dist/drizzle/oauth-connected-state.d.mts +1 -1
  15. package/dist/drizzle/oauth-registration.d.mts +1 -1
  16. package/dist/drizzle/oauth-registration.mjs +3 -2
  17. package/dist/drizzle/oauth-registration.mjs.map +1 -1
  18. package/dist/oauth/OAuthConnectedRevocations.d.mts +10 -0
  19. package/dist/oauth/OAuthRegistrationIntents.d.mts +9 -0
  20. package/dist/oauth/accountsModels.d.mts +5 -0
  21. package/dist/oauth/connected.d.mts +22 -0
  22. package/dist/oauth/connectedModels.d.mts +115 -0
  23. package/dist/oauth/definition.d.mts +111 -3
  24. package/dist/oauth/github/identity.mjs +11 -9
  25. package/dist/oauth/github/identity.mjs.map +1 -1
  26. package/dist/oauth/github/profile.d.mts +61 -0
  27. package/dist/oauth/github/profile.mjs +72 -0
  28. package/dist/oauth/github/profile.mjs.map +1 -0
  29. package/dist/oauth/github/protocol.mjs +2 -2
  30. package/dist/oauth/github/protocol.mjs.map +1 -1
  31. package/dist/oauth/openid-client/connected/protocol.mjs +3 -0
  32. package/dist/oauth/openid-client/connected/protocol.mjs.map +1 -1
  33. package/dist/oauth/openid-client/profile.d.mts +39 -0
  34. package/dist/oauth/openid-client/profile.mjs +58 -0
  35. package/dist/oauth/openid-client/profile.mjs.map +1 -0
  36. package/dist/oauth/openid-client/protocol.mjs +3 -0
  37. package/dist/oauth/openid-client/protocol.mjs.map +1 -1
  38. package/dist/oauth/registrationModels.d.mts +22 -0
  39. package/dist/oauth/registrationModels.mjs +4 -1
  40. package/dist/oauth/registrationModels.mjs.map +1 -1
  41. package/dist/oauth/registrationSecrets.mjs +1 -0
  42. package/dist/oauth/registrationSecrets.mjs.map +1 -1
  43. package/dist/oauth/signInModels.d.mts +18 -0
  44. package/dist/oauth/signInModels.mjs +11 -1
  45. package/dist/oauth/signInModels.mjs.map +1 -1
  46. package/dist/oauth/signInModule.d.mts +43 -4
  47. package/dist/oauth/signInModule.mjs +1 -1
  48. package/dist/oauth/signInModule.mjs.map +1 -1
  49. package/dist/oauth/signInSnapshot.mjs +1 -1
  50. package/dist/oauth/signInSnapshot.mjs.map +1 -1
  51. package/package.json +1 -1
  52. package/src/GitHub.ts +1 -0
  53. package/src/OpenIdClient.ts +2 -0
  54. package/src/drizzle/oauth-registration.ts +4 -0
  55. package/src/oauth/github/identity.ts +11 -7
  56. package/src/oauth/github/profile.ts +64 -0
  57. package/src/oauth/github/protocol.ts +3 -2
  58. package/src/oauth/openid-client/connected/protocol.ts +4 -0
  59. package/src/oauth/openid-client/profile.ts +68 -0
  60. package/src/oauth/openid-client/protocol.ts +4 -0
  61. package/src/oauth/registrationModels.ts +4 -0
  62. package/src/oauth/registrationSecrets.ts +1 -0
  63. package/src/oauth/signInModels.ts +18 -0
  64. package/src/oauth/signInModule.ts +4 -0
  65. package/src/oauth/signInSnapshot.ts +2 -1
package/package.json CHANGED
@@ -1 +1 @@
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}}}
1
+ {"name":"@yielded/auth","version":"0.1.0-beta.5","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
@@ -15,3 +15,4 @@ export {
15
15
  } from "./oauth/github/protocol";
16
16
 
17
17
  export { gitHubOAuthAppProviderKey } from "./oauth/github/identity";
18
+ export { GitHubUserProfile } from "./oauth/github/profile";
@@ -11,3 +11,5 @@ export {
11
11
  makeOpenIdClientOAuthProtocol,
12
12
  openIdClientOAuthProtocolLayer,
13
13
  } from "./oauth/openid-client/protocol";
14
+
15
+ export { OidcUserProfile } from "./oauth/openid-client/profile";
@@ -11,6 +11,7 @@ import {
11
11
  } from "../oauth/registrationModels";
12
12
  import {
13
13
  OAuthCredentialSnapshot,
14
+ OAuthDisplayProfile,
14
15
  OAuthSignInTransactionContext,
15
16
  type OAuthExternalIdentity,
16
17
  } from "../oauth/signInModels";
@@ -25,6 +26,7 @@ import { invariant, oauthIdentityKey, sameIdentity, storage } from "./oauth-stat
25
26
  export const intentStorage = storage(OAuthRegistrationIntent);
26
27
  const decisionStorage = storage(OAuthRegistrationDecision);
27
28
  const contextStorage = storage(OAuthSignInTransactionContext);
29
+ const profileStorage = storage(Schema.NullOr(OAuthDisplayProfile));
28
30
 
29
31
  const reservationStorage = storage(
30
32
  Schema.Struct({
@@ -174,6 +176,8 @@ export const settleRegistrationIntent = (mapping: any, input: any) =>
174
176
 
175
177
  invariant(
176
178
  sameIdentity(intent.identity, identity) &&
179
+ profileStorage.encode(intent.profile ?? null) ===
180
+ profileStorage.encode(input.identity.profile ?? null) &&
177
181
  intent.claimId === input.claim.claimId &&
178
182
  intent.claimedAtMillis === input.claim.claimedAtMillis &&
179
183
  contextStorage.encode(c) === contextStorage.encode(context),
@@ -3,24 +3,28 @@ import { Effect, Schema } from "effect";
3
3
  import type { PlainOAuthIdentity } from "../openid-client/models";
4
4
  import { OAuthProviderKey } from "../schema";
5
5
  import { OAuthProtocolRejected } from "../signInErrors";
6
+ import { GitHubUserProfile } from "./profile";
6
7
 
7
8
  export const gitHubOAuthAppProviderKey = OAuthProviderKey.make("github");
8
9
 
9
- const identity = Schema.Struct({
10
- id: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: Number.MAX_SAFE_INTEGER })),
11
- login: Schema.optionalKey(Schema.NonEmptyString.check(Schema.isMaxLength(256))),
12
- });
13
-
14
10
  // oxlint-disable-next-line no-restricted-properties -- GitHub /user is an untyped, freshly authenticated JSON boundary.
15
- const decode = Schema.decodeUnknownEffect(identity);
11
+ const decode = Schema.decodeUnknownEffect(GitHubUserProfile);
16
12
 
17
13
  export const decodeGitHubIdentity = Effect.fn("GitHubOAuthApp.decodeIdentity")(function* (
18
14
  body: unknown,
19
15
  ): Effect.fn.Return<PlainOAuthIdentity, OAuthProtocolRejected> {
20
16
  const value = yield* decode(body).pipe(Effect.mapError(() => OAuthProtocolRejected.make({})));
17
+ const displayName = value.name?.trim() || value.login;
21
18
 
22
19
  return {
23
20
  subject: String(value.id),
24
- ...(value.login === undefined ? {} : { profile: { displayName: value.login } }),
21
+ profile: {
22
+ ...(displayName === undefined ? {} : { displayName }),
23
+ ...(value.login === undefined ? {} : { handle: value.login }),
24
+ ...(value.avatar_url === undefined ? {} : { avatarUrl: value.avatar_url }),
25
+ ...(value.html_url === undefined ? {} : { profileUrl: value.html_url }),
26
+ ...(value.email === null || value.email === undefined ? {} : { email: value.email }),
27
+ providerData: value,
28
+ },
25
29
  };
26
30
  });
@@ -0,0 +1,64 @@
1
+ import { Schema } from "effect";
2
+
3
+ const text = Schema.String.check(Schema.isMaxLength(2048));
4
+ const name = Schema.String.check(Schema.isMaxLength(256));
5
+ const count = Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER }));
6
+ const optionalText = Schema.optionalKey(text);
7
+ const nullableText = Schema.optionalKey(Schema.NullOr(text));
8
+
9
+ /** All documented GitHub /user fields, with provider spelling and nulls retained.
10
+ * Only the numeric ID establishes identity. Other fields are optional because
11
+ * availability differs by permission and provider response. This does not fetch
12
+ * repositories, email lists, or any additional endpoint. Unknown fields are omitted.
13
+ * URLs are metadata, not approved redirect or server-fetch targets. */
14
+ export const GitHubUserProfile = Schema.Struct({
15
+ id: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: Number.MAX_SAFE_INTEGER })),
16
+ login: Schema.optionalKey(Schema.NonEmptyString.check(Schema.isMaxLength(256))),
17
+ name: Schema.optionalKey(Schema.NullOr(name)),
18
+ user_view_type: optionalText,
19
+ node_id: optionalText,
20
+ avatar_url: optionalText,
21
+ gravatar_id: nullableText,
22
+ url: optionalText,
23
+ html_url: optionalText,
24
+ followers_url: optionalText,
25
+ following_url: optionalText,
26
+ gists_url: optionalText,
27
+ starred_url: optionalText,
28
+ subscriptions_url: optionalText,
29
+ organizations_url: optionalText,
30
+ repos_url: optionalText,
31
+ events_url: optionalText,
32
+ received_events_url: optionalText,
33
+ type: optionalText,
34
+ site_admin: Schema.optionalKey(Schema.Boolean),
35
+ company: nullableText,
36
+ blog: nullableText,
37
+ location: nullableText,
38
+ email: Schema.optionalKey(Schema.NullOr(Schema.String.check(Schema.isMaxLength(320)))),
39
+ notification_email: Schema.optionalKey(
40
+ Schema.NullOr(Schema.String.check(Schema.isMaxLength(320))),
41
+ ),
42
+ hireable: Schema.optionalKey(Schema.NullOr(Schema.Boolean)),
43
+ bio: nullableText,
44
+ twitter_username: nullableText,
45
+ public_repos: Schema.optionalKey(count),
46
+ public_gists: Schema.optionalKey(count),
47
+ followers: Schema.optionalKey(count),
48
+ following: Schema.optionalKey(count),
49
+ created_at: optionalText,
50
+ updated_at: optionalText,
51
+ private_gists: Schema.optionalKey(count),
52
+ total_private_repos: Schema.optionalKey(count),
53
+ owned_private_repos: Schema.optionalKey(count),
54
+ disk_usage: Schema.optionalKey(count),
55
+ collaborators: Schema.optionalKey(count),
56
+ two_factor_authentication: Schema.optionalKey(Schema.Boolean),
57
+ plan: Schema.optionalKey(
58
+ Schema.Struct({ collaborators: count, name: text, space: count, private_repos: count }),
59
+ ),
60
+ business_plus: Schema.optionalKey(Schema.Boolean),
61
+ ldap_dn: optionalText,
62
+ });
63
+
64
+ export type GitHubUserProfile = typeof GitHubUserProfile.Type;
@@ -29,7 +29,8 @@ import type {
29
29
 
30
30
  const unavailable = () => OAuthUnavailable.make({});
31
31
  const invalid = () => OpenIdClientConfigurationError.make({ reason: "provider" });
32
- const issuer = OAuthIssuer.make("https://github.com");
32
+ // GitHub's OAuth authorization server issuer, including its RFC 9207 callback value.
33
+ const issuer = OAuthIssuer.make("https://github.com/login/oauth");
33
34
 
34
35
  const headers = Object.freeze({
35
36
  Accept: "application/vnd.github+json",
@@ -92,7 +93,7 @@ const provider = (
92
93
  issuance: registration.issuance,
93
94
  issuer,
94
95
  protocol: "oauth",
95
- responseIssuerMode: "unsupported",
96
+ responseIssuerMode: "required",
96
97
  clientId: registration.clientId,
97
98
  authentication: { method: "client_secret_post", secret: registration.clientSecret },
98
99
  callbacks: registration.callbacks,
@@ -23,6 +23,7 @@ import {
23
23
  } from "../compatibility";
24
24
  import { clientAuthentication } from "../configuration";
25
25
  import { type OpenIdClientConfigurationError } from "../models";
26
+ import { decodeOidcProfile } from "../profile";
26
27
  import { ProviderRevocation } from "../ProviderRevocation";
27
28
  import { boundedFetch } from "../transport";
28
29
  import {
@@ -372,8 +373,11 @@ export const makeConnectedProtocolWithCompatibility = Effect.fn(
372
373
  )
373
374
  return yield* unavailable();
374
375
 
376
+ const profile = yield* decodeOidcProfile(raw).pipe(Effect.mapError(unavailable));
377
+
375
378
  return {
376
379
  identity: { provider: provider.provider, issuer: provider.issuer, subject: claims.sub },
380
+ ...(profile === undefined ? {} : { profile }),
377
381
  continuation: previous?.continuation ?? {
378
382
  _tag: "Oidc" as const,
379
383
  clientId: provider.clientId,
@@ -0,0 +1,68 @@
1
+ import { Effect, Schema } from "effect";
2
+
3
+ import { OAuthProtocolRejected } from "../signInErrors";
4
+ import type { OAuthDisplayProfile } from "../signInModels";
5
+
6
+ const text = Schema.String.check(Schema.isMaxLength(256));
7
+ const url = Schema.String.check(Schema.isMaxLength(2048));
8
+
9
+ /** Standard OpenID Connect user claims returned in a verified ID token. This
10
+ * does not request additional scopes or fetch UserInfo. Protocol claims and
11
+ * credentials are excluded; values such as email_verified describe the provider's
12
+ * assertion and never authorize local account linking by themselves. */
13
+ export const OidcUserProfile = Schema.Struct({
14
+ name: Schema.optionalKey(text),
15
+ given_name: Schema.optionalKey(text),
16
+ family_name: Schema.optionalKey(text),
17
+ middle_name: Schema.optionalKey(text),
18
+ nickname: Schema.optionalKey(text),
19
+ preferred_username: Schema.optionalKey(text),
20
+ profile: Schema.optionalKey(url),
21
+ picture: Schema.optionalKey(url),
22
+ website: Schema.optionalKey(url),
23
+ email: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(320))),
24
+ email_verified: Schema.optionalKey(Schema.Boolean),
25
+ gender: Schema.optionalKey(text),
26
+ birthdate: Schema.optionalKey(text),
27
+ zoneinfo: Schema.optionalKey(text),
28
+ locale: Schema.optionalKey(text),
29
+ phone_number: Schema.optionalKey(text),
30
+ phone_number_verified: Schema.optionalKey(Schema.Boolean),
31
+ address: Schema.optionalKey(
32
+ Schema.Struct({
33
+ formatted: Schema.optionalKey(url),
34
+ street_address: Schema.optionalKey(url),
35
+ locality: Schema.optionalKey(text),
36
+ region: Schema.optionalKey(text),
37
+ postal_code: Schema.optionalKey(text),
38
+ country: Schema.optionalKey(text),
39
+ }),
40
+ ),
41
+ updated_at: Schema.optionalKey(
42
+ Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER })),
43
+ ),
44
+ });
45
+
46
+ export type OidcUserProfile = typeof OidcUserProfile.Type;
47
+
48
+ export const decodeOidcProfile = Effect.fn("OpenIdClient.decodeProfile")(function* (
49
+ claims: unknown,
50
+ ): Effect.fn.Return<OAuthDisplayProfile | undefined, OAuthProtocolRejected> {
51
+ // oxlint-disable-next-line no-restricted-properties -- Select standard user claims from an already verified ID token.
52
+ const profile = yield* Schema.decodeUnknownEffect(OidcUserProfile)(claims).pipe(
53
+ Effect.mapError(() => OAuthProtocolRejected.make({})),
54
+ );
55
+
56
+ if (Object.keys(profile).length === 0) return undefined;
57
+ const displayName = profile.name?.trim() || profile.preferred_username;
58
+
59
+ return {
60
+ ...(displayName === undefined ? {} : { displayName }),
61
+ ...(profile.preferred_username === undefined ? {} : { handle: profile.preferred_username }),
62
+ ...(profile.picture === undefined ? {} : { avatarUrl: profile.picture }),
63
+ ...(profile.profile === undefined ? {} : { profileUrl: profile.profile }),
64
+ ...(profile.email === undefined ? {} : { email: profile.email }),
65
+ ...(profile.email_verified === undefined ? {} : { emailVerified: profile.email_verified }),
66
+ providerData: profile,
67
+ };
68
+ });
@@ -27,6 +27,7 @@ import {
27
27
  type OpenIdClientConfigurationError,
28
28
  type OpenIdClientOAuthProtocolOptions,
29
29
  } from "./models";
30
+ import { decodeOidcProfile } from "./profile";
30
31
  import { boundedFetch } from "./transport";
31
32
 
32
33
  const beginInput = Schema.Struct({
@@ -357,8 +358,11 @@ export const makeOpenIdClientOAuthProtocol = Effect.fn("makeOpenIdClientOAuthPro
357
358
  )
358
359
  return yield* rejected();
359
360
 
361
+ const profile = yield* decodeOidcProfile(exchanged.claims);
362
+
360
363
  return yield* snapshotOAuth(OAuthVerifiedExternalIdentity, {
361
364
  identity: { provider: provider.provider, issuer: provider.issuer, subject: claims.sub },
365
+ ...(profile === undefined ? {} : { profile }),
362
366
  ...(claims.auth_time === undefined
363
367
  ? {}
364
368
  : {
@@ -5,6 +5,7 @@ import { TokenDigest } from "../Schema";
5
5
  import {
6
6
  OAuthClaimId,
7
7
  OAuthCommandId,
8
+ OAuthDisplayProfile,
8
9
  OAuthExternalIdentity,
9
10
  OAuthInstant,
10
11
  OAuthModuleId,
@@ -46,6 +47,9 @@ export const OAuthRegistrationIntent = Schema.Struct({
46
47
  claimId: OAuthClaimId,
47
48
  claimedAtMillis: OAuthInstant,
48
49
  identity: OAuthExternalIdentity,
50
+ /** Original authenticated provider snapshot, available only to server-side
51
+ * provisioning authority. It is not caller-supplied registration data. */
52
+ profile: Schema.optionalKey(OAuthDisplayProfile),
49
53
  verifiedAtMillis: OAuthInstant,
50
54
  credentialDigest: OAuthRegistrationBearerDigest,
51
55
  issuedAtMillis: OAuthInstant,
@@ -100,6 +100,7 @@ export const prepare = Effect.fn("OAuthRegistration.prepareIntent")(function* (
100
100
  claimId: claim.claimId,
101
101
  claimedAtMillis: claim.claimedAtMillis,
102
102
  identity: identity.identity,
103
+ ...(identity.profile === undefined ? {} : { profile: identity.profile }),
103
104
  verifiedAtMillis,
104
105
  credentialDigest: yield* credentialDigest(
105
106
  claim.flow.context.moduleId,
@@ -127,11 +127,29 @@ export const OAuthExternalIdentity = Schema.Struct({
127
127
  subject: Schema.NonEmptyString.check(Schema.isMaxLength(1024)),
128
128
  });
129
129
 
130
+ /** Provider-supplied metadata, never local identity or linking authority. Adapters
131
+ * project identity responses into this bounded JSON snapshot; tokens and protocol
132
+ * secrets do not belong here. Applications select their own public session claims. */
130
133
  export const OAuthDisplayProfile = Schema.Struct({
131
134
  displayName: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(256))),
132
135
  handle: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(256))),
136
+ avatarUrl: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(2048))),
137
+ profileUrl: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(2048))),
138
+ email: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(320))),
139
+ emailVerified: Schema.optionalKey(Schema.Boolean),
140
+ /** Provider-specific fields. Use the provider's exported profile Schema to
141
+ * decode them. Availability follows the existing provider permissions. */
142
+ providerData: Schema.optionalKey(
143
+ Schema.JsonObject.check(
144
+ Schema.makeFilter(
145
+ (value) => new TextEncoder().encode(JSON.stringify(value)).length <= 65_536,
146
+ ),
147
+ ),
148
+ ),
133
149
  });
134
150
 
151
+ export type OAuthDisplayProfile = typeof OAuthDisplayProfile.Type;
152
+
135
153
  export const OAuthVerifiedExternalIdentity = Schema.Struct({
136
154
  identity: OAuthExternalIdentity,
137
155
  upstreamAuthenticatedAt: Schema.optionalKey(Schema.DateTimeUtcFromMillis),
@@ -139,6 +139,9 @@ export const makeOAuthMethod = <
139
139
  {
140
140
  readonly resolve: (
141
141
  credential: OAuthCredentialSnapshot,
142
+ /** Fresh provider metadata, after exact local credential/identity matching.
143
+ * Select application claims explicitly; profile email grants no linking authority. */
144
+ verified: OAuthVerifiedExternalIdentity,
142
145
  ) => Effect.Effect<Claims["Type"], OAuthUnavailable>;
143
146
  }
144
147
  >(`effect-auth/oauth/${moduleId.length}:${moduleId}/Claims`);
@@ -681,6 +684,7 @@ export const makeOAuthMethod = <
681
684
 
682
685
  const claims = yield* resolveClaims(
683
686
  snapshotOAuthSync(OAuthCredentialSnapshot, credential),
687
+ snapshotOAuthSync(OAuthVerifiedExternalIdentity, identity),
684
688
  );
685
689
 
686
690
  const established = yield* completeAuthentication({
@@ -16,7 +16,8 @@ export const snapshotOAuthSync = <S extends Schema.Codec<unknown, unknown, never
16
16
  value: S["Type"],
17
17
  ): S["Type"] => {
18
18
  try {
19
- const codec = Schema.toCodecJson(Schema.toType(schema));
19
+ // JSON fields can otherwise retain nested input references through validation.
20
+ const codec = Schema.fromJsonString(Schema.toCodecJson(Schema.toType(schema)));
20
21
  const result = Schema.decodeSync(codec)(Schema.encodeSync(codec)(value));
21
22
 
22
23
  freezeOAuth(result);