@gasboost/auth-realtime-firebase 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +196 -0
- package/dist/FirebaseAuthHook.d.ts +16 -0
- package/dist/FirebaseAuthHook.js +22 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +17 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# @gasboost/auth-realtime-firebase
|
|
2
|
+
|
|
3
|
+
Firebase Authentication integration adapter for `@gasboost/auth`.
|
|
4
|
+
|
|
5
|
+
`@gasboost/auth` の認証 lifecycle と、`@gasboost/realtime-firebase` の Firebase Custom Token generation を接続します。
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
@gasboost/auth
|
|
9
|
+
↓ afterSignIn
|
|
10
|
+
@gasboost/auth-realtime-firebase
|
|
11
|
+
↓
|
|
12
|
+
@gasboost/realtime-firebase
|
|
13
|
+
↓
|
|
14
|
+
Firebase Custom Token
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add \
|
|
21
|
+
@gasboost/auth \
|
|
22
|
+
@gasboost/auth-realtime-firebase \
|
|
23
|
+
@gasboost/realtime-firebase
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { AppsScriptAuth, type EmailPasswordAuthOptions } from "@gasboost/auth";
|
|
30
|
+
import {
|
|
31
|
+
FirebaseAuthHook,
|
|
32
|
+
type FirebaseAuthHookResult,
|
|
33
|
+
} from "@gasboost/auth-realtime-firebase";
|
|
34
|
+
|
|
35
|
+
const firebase = new FirebaseAuthHook({
|
|
36
|
+
serviceAccount: {
|
|
37
|
+
email: serviceAccountEmail,
|
|
38
|
+
privateKey,
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
utilities: Utilities,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const auth = new AppsScriptAuth<
|
|
45
|
+
EmailPasswordAuthOptions,
|
|
46
|
+
FirebaseAuthHookResult
|
|
47
|
+
>({
|
|
48
|
+
repository,
|
|
49
|
+
|
|
50
|
+
runtime: {
|
|
51
|
+
utilities: Utilities,
|
|
52
|
+
session: Session,
|
|
53
|
+
cacheService: CacheService,
|
|
54
|
+
propertiesService: PropertiesService,
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
session: {
|
|
58
|
+
storageType: "cache",
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
emailPassword: {
|
|
62
|
+
enabled: true,
|
|
63
|
+
pepper,
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
hooks: {
|
|
67
|
+
afterSignIn: firebase.afterSignIn,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Sign In result から Firebase Custom Token を取得できます。
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const result = await auth.signIn.email({
|
|
76
|
+
email: "user@example.com",
|
|
77
|
+
password: "password",
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
result.user;
|
|
81
|
+
result.session;
|
|
82
|
+
result.hooks.customToken;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## UID
|
|
86
|
+
|
|
87
|
+
Gasboost Auth の `User.id` を Firebase Authentication の `uid` として利用します。
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
Auth User.id
|
|
91
|
+
↓
|
|
92
|
+
Firebase uid
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
adapter側で別のFirebase User IDを管理する必要はありません。
|
|
96
|
+
|
|
97
|
+
## Custom Claims
|
|
98
|
+
|
|
99
|
+
`claims` を指定すると Firebase Custom Token の custom claims を生成できます。
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
const firebase = new FirebaseAuthHook({
|
|
103
|
+
serviceAccount: {
|
|
104
|
+
email: serviceAccountEmail,
|
|
105
|
+
privateKey,
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
utilities: Utilities,
|
|
109
|
+
|
|
110
|
+
claims: ({ user, session }) => ({
|
|
111
|
+
storeId: "store-1",
|
|
112
|
+
authSessionId: session.id,
|
|
113
|
+
}),
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
生成されたclaimsはFirebase Authentication後、
|
|
118
|
+
|
|
119
|
+
```text
|
|
120
|
+
auth.token.storeId
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
などとしてFirebase Security Rulesから参照できます。
|
|
124
|
+
|
|
125
|
+
## Service Account
|
|
126
|
+
|
|
127
|
+
Firebase Custom Token は Google Service Account によって署名する必要があります。
|
|
128
|
+
|
|
129
|
+
このpackageでは `@gasboost/realtime-firebase` のローカル署名方式を利用するため、以下が必要です。
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
serviceAccount: {
|
|
133
|
+
email: serviceAccountEmail,
|
|
134
|
+
privateKey,
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
private key はソースコードへ直接埋め込まず、安全なcredential storageから取得してください。
|
|
139
|
+
|
|
140
|
+
Service Account credentialの保存やSecret Manager integrationは、このpackageの責務ではありません。
|
|
141
|
+
|
|
142
|
+
## GAS Utilities
|
|
143
|
+
|
|
144
|
+
署名処理にはGoogle Apps Script標準の `Utilities` を利用できます。
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
const firebase = new FirebaseAuthHook({
|
|
148
|
+
serviceAccount,
|
|
149
|
+
utilities: Utilities,
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
公開APIはGAS固有型には依存していないため、実際の署名処理は `@gasboost/realtime-firebase` が要求する最小interfaceを通じて実行されます。
|
|
154
|
+
|
|
155
|
+
## Client
|
|
156
|
+
|
|
157
|
+
Sign Inで取得したCustom Tokenはfrontendへ返し、Firebase公式SDKへ渡します。
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
import { getAuth, signInWithCustomToken } from "firebase/auth";
|
|
161
|
+
|
|
162
|
+
await signInWithCustomToken(getAuth(), result.hooks.customToken);
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
このpackageはFirebase Browser SDKをラップしません。
|
|
166
|
+
|
|
167
|
+
## Package Boundary
|
|
168
|
+
|
|
169
|
+
このpackageが担当するのは integration のみです。
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
AfterSignInContext
|
|
173
|
+
├─ User
|
|
174
|
+
└─ Session
|
|
175
|
+
↓
|
|
176
|
+
FirebaseAuthHook
|
|
177
|
+
↓
|
|
178
|
+
uid / claims
|
|
179
|
+
↓
|
|
180
|
+
FirebaseCustomToken.generate()
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
以下は担当しません。
|
|
184
|
+
|
|
185
|
+
- Gasboost Auth の認証処理
|
|
186
|
+
- Firebase Custom Token JWT生成ロジック
|
|
187
|
+
- Firebase Admin SDK
|
|
188
|
+
- Firebase Browser SDK
|
|
189
|
+
- `signInWithCustomToken()` の実行
|
|
190
|
+
- Firebase Auth session管理
|
|
191
|
+
- Service Account credential storage
|
|
192
|
+
- Secret Manager integration
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
MIT
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AfterSignInContext, AfterSignInHook } from "@gasboost/auth";
|
|
2
|
+
import { type FirebaseCustomClaims, type FirebaseCustomTokenUtilities, type FirebaseServiceAccount } from "@gasboost/realtime-firebase";
|
|
3
|
+
export type FirebaseAuthHookResult = {
|
|
4
|
+
readonly customToken: string;
|
|
5
|
+
};
|
|
6
|
+
export declare class FirebaseAuthHook {
|
|
7
|
+
private readonly serviceAccount;
|
|
8
|
+
private readonly utilities;
|
|
9
|
+
private readonly claims;
|
|
10
|
+
constructor({ serviceAccount, utilities, claims, }: {
|
|
11
|
+
serviceAccount: FirebaseServiceAccount;
|
|
12
|
+
utilities: FirebaseCustomTokenUtilities;
|
|
13
|
+
claims?: (context: AfterSignInContext) => FirebaseCustomClaims;
|
|
14
|
+
});
|
|
15
|
+
readonly afterSignIn: AfterSignInHook<FirebaseAuthHookResult>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FirebaseAuthHook = void 0;
|
|
4
|
+
const realtime_firebase_1 = require("@gasboost/realtime-firebase");
|
|
5
|
+
class FirebaseAuthHook {
|
|
6
|
+
constructor({ serviceAccount, utilities, claims, }) {
|
|
7
|
+
this.afterSignIn = (context) => {
|
|
8
|
+
return {
|
|
9
|
+
customToken: realtime_firebase_1.FirebaseCustomToken.generate({
|
|
10
|
+
uid: context.user.id,
|
|
11
|
+
claims: this.claims?.(context),
|
|
12
|
+
serviceAccount: this.serviceAccount,
|
|
13
|
+
utilities: this.utilities,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
this.serviceAccount = serviceAccount;
|
|
18
|
+
this.utilities = utilities;
|
|
19
|
+
this.claims = claims;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.FirebaseAuthHook = FirebaseAuthHook;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./FirebaseAuthHook";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./FirebaseAuthHook"), exports);
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gasboost/auth-realtime-firebase",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Firebase Authentication integration adapter for @gasboost/auth.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"google-apps-script",
|
|
7
|
+
"gas",
|
|
8
|
+
"authentication",
|
|
9
|
+
"auth",
|
|
10
|
+
"firebase",
|
|
11
|
+
"firebase-authentication",
|
|
12
|
+
"custom-token",
|
|
13
|
+
"typescript",
|
|
14
|
+
"gasboost"
|
|
15
|
+
],
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"default": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/gasboost/auth.git",
|
|
32
|
+
"directory": "packages/auth-realtime-firebase"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/gasboost/auth/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/gasboost/auth#readme",
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@gasboost/realtime-firebase": "^0.2.0",
|
|
43
|
+
"@gasboost/auth": "0.2.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@gasboost/fake-node": "^0.1.2",
|
|
47
|
+
"@types/node": "^26.4.1"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"format": "prettier --check . --config ../../.prettierrc.json --ignore-path ../../.prettierignore",
|
|
51
|
+
"format:fix": "prettier --write . --config ../../.prettierrc.json --ignore-path ../../.prettierignore",
|
|
52
|
+
"lint": "eslint . --config ../../eslint.config.mjs",
|
|
53
|
+
"typecheck": "tsc --noEmit",
|
|
54
|
+
"test": "vitest run",
|
|
55
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json"
|
|
56
|
+
}
|
|
57
|
+
}
|