@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 +4 -26
- package/dist/firebase/social-auth.d.ts +0 -77
- package/dist/firebase/social-auth.js +0 -71
- package/package.json +3 -3
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
|
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
|
|
112
|
-
"@rdlabo/workers-timezone": "0.12.3
|
|
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",
|