@rdlabo/workers-hono-kit 0.12.3-beta.pr51.sha3289ea609bb4 → 0.12.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
@@ -82,32 +82,10 @@ compatibility aliases keep the same runtime identity and signatures; there is no
82
82
  Kit-owned helpers such as `reopenGuardedPaymentFailedSet`, `/mysql` `createContainerRuntime`, and
83
83
  Firebase/auth/KV/Stripe test helpers are not deprecated by this migration.
84
84
 
85
- ### Social auth (Google / Apple)
86
-
87
- Root exports `verifyGoogleIdentityToken`, `verifyAppleIdentityToken`,
88
- `hasFirebaseProviderIdentity`, and `createAppleClientSecret` cover reusable OIDC subject
89
- verification, Firebase identity matching, and Apple `client_secret` signing. Applications keep
90
- ownership of HTTP responses, persistence, and provider token exchange or revocation.
91
-
92
- `hasFirebaseProviderIdentity` expects a **verified** Firebase ID-token payload. Pass
93
- `requireSignInProvider: true` when an endpoint requires sign-in through that provider
94
- (subject linked **and** `firebase.sign_in_provider` matches). Leave it `false` (default)
95
- for link/unlink checks or combined login/link endpoints that also accept sessions established
96
- through another provider. This policy belongs to the application.
97
-
98
- ```ts
99
- import { hasFirebaseProviderIdentity, verifyGoogleIdentityToken } from '@rdlabo/workers-hono-kit';
100
-
101
- // firebaseVerifier is the application's configured FirebaseVerifier.
102
- const verifiedFirebaseToken = await firebaseVerifier.verifyIdToken(firebaseIdToken);
103
- const subject = await verifyGoogleIdentityToken(googleIdToken, GOOGLE_CLIENT_IDS);
104
- // login: require active Google sign-in
105
- if (!hasFirebaseProviderIdentity(verifiedFirebaseToken, 'google.com', subject, true)) {
106
- return c.json({ error: 'Google identity mismatch' }, 401);
107
- }
108
- // link / unlink: subject present is enough
109
- // hasFirebaseProviderIdentity(verifiedFirebaseToken, 'google.com', subject)
110
- ```
85
+ Google and Apple login endpoints can use the root exports `verifyGoogleIdentityToken`,
86
+ `verifyAppleIdentityToken`, and `hasFirebaseProviderIdentity`. Apple token exchange can additionally
87
+ use `createAppleClientSecret`. Applications keep ownership of HTTP responses, persistence, and
88
+ provider token exchange or revocation; the Kit owns only reusable token verification and signing.
111
89
 
112
90
  ## Documentation
113
91
 
@@ -1,90 +1,13 @@
1
1
  import type { JWTVerifyGetKey } from 'jose';
2
2
  import type { DecodedIdToken } from './firebase-verifier.js';
3
- /** Apple Sign In OIDC issuer (`iss`) expected by {@link verifyAppleIdentityToken}. */
4
3
  export declare const APPLE_IDENTITY_ISSUER = "https://appleid.apple.com";
5
- /**
6
- * Google OIDC issuers accepted by {@link verifyGoogleIdentityToken}.
7
- *
8
- * Google issues tokens with either the HTTPS form or the host-only form of
9
- * `accounts.google.com`; both are listed so verification matches either claim.
10
- */
11
4
  export declare const GOOGLE_IDENTITY_ISSUERS: readonly ["https://accounts.google.com", "accounts.google.com"];
12
- /**
13
- * Verify an Apple identity token and return its `sub` (Apple user id).
14
- *
15
- * Checks signature against Apple's JWKS (or an injected key resolver), enforces
16
- * {@link APPLE_IDENTITY_ISSUER}, and requires `aud` to equal the configured Services ID /
17
- * bundle id (`audience`).
18
- *
19
- * @param idToken - Raw Apple identity token JWT from Sign in with Apple.
20
- * @param audience - Expected `aud` claim (Apple Services ID or native bundle id).
21
- * @param getKey - Optional JWKS / key resolver; defaults to Apple's remote JWKS. Inject a
22
- * static key in tests to avoid network I/O.
23
- * @returns The token `sub` (Apple user identifier).
24
- * @throws If signature, issuer, audience, or expiry fail verification, or `sub` is missing.
25
- */
26
5
  export declare const verifyAppleIdentityToken: (idToken: string, audience: string, getKey?: JWTVerifyGetKey) => Promise<string>;
27
- /**
28
- * Verify a Google identity token and return its `sub` (Google user id).
29
- *
30
- * Checks signature against Google's OAuth2 certs (or an injected key resolver), accepts either
31
- * issuer in {@link GOOGLE_IDENTITY_ISSUERS}, and requires `aud` to match the configured OAuth
32
- * client id(s) (`audience`).
33
- *
34
- * @param idToken - Raw Google ID token JWT.
35
- * @param audience - Expected `aud` claim: a single OAuth client id, or a list when native and
36
- * web clients share one login endpoint.
37
- * @param getKey - Optional JWKS / key resolver; defaults to Google's remote certs. Inject a
38
- * static key in tests to avoid network I/O.
39
- * @returns The token `sub` (Google user identifier).
40
- * @throws If signature, issuer, audience, or expiry fail verification, or `sub` is missing.
41
- */
42
6
  export declare const verifyGoogleIdentityToken: (idToken: string, audience: string | readonly string[], getKey?: JWTVerifyGetKey) => Promise<string>;
43
- /**
44
- * Return whether a **verified** Firebase ID token already carries the given provider subject.
45
- *
46
- * Reads `firebase.identities[providerId]` for `subject`. When `requireSignInProvider` is true,
47
- * also requires `firebase.sign_in_provider === providerId` so the session was established with
48
- * that provider (login), not merely that the identity is linked while signed in another way.
49
- *
50
- * @remarks
51
- * `token` must already be a verified Firebase ID-token payload (for example from
52
- * {@link FirebaseVerifier.verifyIdToken} or auth middleware). This helper does not verify the
53
- * Firebase JWT itself.
54
- *
55
- * Typical policy:
56
- * - **Login** (`requireSignInProvider: true`): subject present and active sign-in provider matches.
57
- * - **Link / unlink / linkage checks** (default `false`): subject present in identities only.
58
- *
59
- * @param token - Verified Firebase ID-token payload (`DecodedIdToken`).
60
- * @param providerId - Firebase provider id (e.g. `'google.com'`, `'apple.com'`).
61
- * @param subject - Provider subject previously returned by {@link verifyGoogleIdentityToken} or
62
- * {@link verifyAppleIdentityToken}.
63
- * @param requireSignInProvider - When `true`, also require `sign_in_provider === providerId`.
64
- * @returns `true` when the identity (and optional active provider) matches.
65
- */
66
7
  export declare const hasFirebaseProviderIdentity: (token: DecodedIdToken, providerId: string, subject: string, requireSignInProvider?: boolean) => boolean;
67
- /**
68
- * Apple developer credentials used to mint a Sign in with Apple `client_secret` JWT.
69
- */
70
8
  export interface AppleClientSecretConfig {
71
- /** PEM-encoded PKCS#8 ES256 private key from the Apple developer key. */
72
9
  privateKey: string;
73
- /** Key id (`kid`) of the Apple developer key. */
74
10
  keyId: string;
75
- /** Apple Team ID used as the JWT `iss` claim. */
76
11
  teamId: string;
77
12
  }
78
- /**
79
- * Create a short-lived Sign in with Apple `client_secret` (ES256 JWT).
80
- *
81
- * The JWT is issued for `clientId` as `sub`, audience {@link APPLE_IDENTITY_ISSUER}, and expires
82
- * 120 seconds after `now`. Used for Apple's token and revoke endpoints.
83
- *
84
- * @param config - Apple Team ID, key id, and PKCS#8 private key.
85
- * @param clientId - Apple Services ID or native bundle id (`sub` claim).
86
- * @param now - Unix time in seconds for `iat` / `exp`; injectable for deterministic tests.
87
- * Defaults to the system clock.
88
- * @returns A compact ES256 JWT suitable as Apple's `client_secret`.
89
- */
90
13
  export declare const createAppleClientSecret: (config: AppleClientSecretConfig, clientId: string, now?: number) => Promise<string>;
@@ -1,29 +1,8 @@
1
1
  import { SignJWT, createRemoteJWKSet, importPKCS8, jwtVerify } from 'jose';
2
- /** Apple Sign In OIDC issuer (`iss`) expected by {@link verifyAppleIdentityToken}. */
3
2
  export const APPLE_IDENTITY_ISSUER = 'https://appleid.apple.com';
4
- /**
5
- * Google OIDC issuers accepted by {@link verifyGoogleIdentityToken}.
6
- *
7
- * Google issues tokens with either the HTTPS form or the host-only form of
8
- * `accounts.google.com`; both are listed so verification matches either claim.
9
- */
10
3
  export const GOOGLE_IDENTITY_ISSUERS = ['https://accounts.google.com', 'accounts.google.com'];
11
4
  const appleJwks = createRemoteJWKSet(new URL(`${APPLE_IDENTITY_ISSUER}/auth/keys`));
12
5
  const googleJwks = createRemoteJWKSet(new URL('https://www.googleapis.com/oauth2/v3/certs'));
13
- /**
14
- * Verify an Apple identity token and return its `sub` (Apple user id).
15
- *
16
- * Checks signature against Apple's JWKS (or an injected key resolver), enforces
17
- * {@link APPLE_IDENTITY_ISSUER}, and requires `aud` to equal the configured Services ID /
18
- * bundle id (`audience`).
19
- *
20
- * @param idToken - Raw Apple identity token JWT from Sign in with Apple.
21
- * @param audience - Expected `aud` claim (Apple Services ID or native bundle id).
22
- * @param getKey - Optional JWKS / key resolver; defaults to Apple's remote JWKS. Inject a
23
- * static key in tests to avoid network I/O.
24
- * @returns The token `sub` (Apple user identifier).
25
- * @throws If signature, issuer, audience, or expiry fail verification, or `sub` is missing.
26
- */
27
6
  export const verifyAppleIdentityToken = async (idToken, audience, getKey = appleJwks) => {
28
7
  const { payload } = await jwtVerify(idToken, getKey, { issuer: APPLE_IDENTITY_ISSUER, audience });
29
8
  if (!payload.sub) {
@@ -31,21 +10,6 @@ export const verifyAppleIdentityToken = async (idToken, audience, getKey = apple
31
10
  }
32
11
  return payload.sub;
33
12
  };
34
- /**
35
- * Verify a Google identity token and return its `sub` (Google user id).
36
- *
37
- * Checks signature against Google's OAuth2 certs (or an injected key resolver), accepts either
38
- * issuer in {@link GOOGLE_IDENTITY_ISSUERS}, and requires `aud` to match the configured OAuth
39
- * client id(s) (`audience`).
40
- *
41
- * @param idToken - Raw Google ID token JWT.
42
- * @param audience - Expected `aud` claim: a single OAuth client id, or a list when native and
43
- * web clients share one login endpoint.
44
- * @param getKey - Optional JWKS / key resolver; defaults to Google's remote certs. Inject a
45
- * static key in tests to avoid network I/O.
46
- * @returns The token `sub` (Google user identifier).
47
- * @throws If signature, issuer, audience, or expiry fail verification, or `sub` is missing.
48
- */
49
13
  export const verifyGoogleIdentityToken = async (idToken, audience, getKey = googleJwks) => {
50
14
  const { payload } = await jwtVerify(idToken, getKey, {
51
15
  issuer: [...GOOGLE_IDENTITY_ISSUERS],
@@ -56,29 +20,6 @@ export const verifyGoogleIdentityToken = async (idToken, audience, getKey = goog
56
20
  }
57
21
  return payload.sub;
58
22
  };
59
- /**
60
- * Return whether a **verified** Firebase ID token already carries the given provider subject.
61
- *
62
- * Reads `firebase.identities[providerId]` for `subject`. When `requireSignInProvider` is true,
63
- * also requires `firebase.sign_in_provider === providerId` so the session was established with
64
- * that provider (login), not merely that the identity is linked while signed in another way.
65
- *
66
- * @remarks
67
- * `token` must already be a verified Firebase ID-token payload (for example from
68
- * {@link FirebaseVerifier.verifyIdToken} or auth middleware). This helper does not verify the
69
- * Firebase JWT itself.
70
- *
71
- * Typical policy:
72
- * - **Login** (`requireSignInProvider: true`): subject present and active sign-in provider matches.
73
- * - **Link / unlink / linkage checks** (default `false`): subject present in identities only.
74
- *
75
- * @param token - Verified Firebase ID-token payload (`DecodedIdToken`).
76
- * @param providerId - Firebase provider id (e.g. `'google.com'`, `'apple.com'`).
77
- * @param subject - Provider subject previously returned by {@link verifyGoogleIdentityToken} or
78
- * {@link verifyAppleIdentityToken}.
79
- * @param requireSignInProvider - When `true`, also require `sign_in_provider === providerId`.
80
- * @returns `true` when the identity (and optional active provider) matches.
81
- */
82
23
  export const hasFirebaseProviderIdentity = (token, providerId, subject, requireSignInProvider = false) => {
83
24
  const firebase = token;
84
25
  const subjects = firebase.firebase?.identities?.[providerId];
@@ -86,18 +27,6 @@ export const hasFirebaseProviderIdentity = (token, providerId, subject, requireS
86
27
  subjects.includes(subject) &&
87
28
  (!requireSignInProvider || firebase.firebase?.sign_in_provider === providerId));
88
29
  };
89
- /**
90
- * Create a short-lived Sign in with Apple `client_secret` (ES256 JWT).
91
- *
92
- * The JWT is issued for `clientId` as `sub`, audience {@link APPLE_IDENTITY_ISSUER}, and expires
93
- * 120 seconds after `now`. Used for Apple's token and revoke endpoints.
94
- *
95
- * @param config - Apple Team ID, key id, and PKCS#8 private key.
96
- * @param clientId - Apple Services ID or native bundle id (`sub` claim).
97
- * @param now - Unix time in seconds for `iat` / `exp`; injectable for deterministic tests.
98
- * Defaults to the system clock.
99
- * @returns A compact ES256 JWT suitable as Apple's `client_secret`.
100
- */
101
30
  export const createAppleClientSecret = async (config, clientId, now = Math.floor(Date.now() / 1000)) => new SignJWT({})
102
31
  .setProtectedHeader({ alg: 'ES256', kid: config.keyId })
103
32
  .setIssuer(config.teamId)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rdlabo/workers-hono-kit",
3
- "version": "0.12.3-beta.pr51.sha3289ea609bb4",
3
+ "version": "0.12.3",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -108,8 +108,8 @@
108
108
  },
109
109
  "peerDependencies": {
110
110
  "@hono/zod-validator": "^0.8.0",
111
- "@rdlabo/workers-mysql": "0.12.3-beta.pr51.sha3289ea609bb4",
112
- "@rdlabo/workers-timezone": "0.12.3-beta.pr51.sha3289ea609bb4",
111
+ "@rdlabo/workers-mysql": "^0.12.3",
112
+ "@rdlabo/workers-timezone": "^0.12.3",
113
113
  "ai": "^6.0.0",
114
114
  "ai-gateway-provider": "^3.1.0",
115
115
  "aws4fetch": "^1.0.20",