豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit f6fd0c4

Browse files
committed
feat(apps): use syncronous login functions to augment firebase authentication.
Using syncronous login functions, only allow google.com users to login and support capturing github tokens for accounts which link their github accout.
1 parent 5f7f2df commit f6fd0c4

File tree

6 files changed

+112
-5
lines changed

6 files changed

+112
-5
lines changed

apps/account-functions/BUILD.bazel

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
load("//tools:defaults.bzl", "esbuild", "ts_library")
2+
3+
package(default_visibility = ["//visibility:private"])
4+
5+
ts_library(
6+
name = "accounts",
7+
srcs = [
8+
"before-create.ts",
9+
"before-sign-in.ts",
10+
"index.ts",
11+
],
12+
visibility = [
13+
"//apps/functions:__pkg__",
14+
],
15+
deps = [
16+
"@npm//gcip-cloud-functions",
17+
],
18+
)
19+
20+
esbuild(
21+
name = "accounts_compiled",
22+
entry_points = [
23+
"index.ts",
24+
],
25+
format = "esm",
26+
visibility = ["//apps:__pkg__"],
27+
deps = [
28+
":accounts",
29+
],
30+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {Auth, https, UserRecord} from 'gcip-cloud-functions';
2+
3+
/** Validate accounts before their creation using google cloud before create syncronous function. */
4+
export const beforeCreate = new Auth().functions().beforeCreateHandler((user: UserRecord) => {
5+
if (user.email && user.email.indexOf('@google.com') === -1) {
6+
throw new https.HttpsError('invalid-argument', `Unauthorized email "${user.email}"`);
7+
}
8+
9+
return {};
10+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {
2+
Auth,
3+
https,
4+
UserRecord,
5+
UserEventUpdateRequest,
6+
AuthEventContext,
7+
} from 'gcip-cloud-functions';
8+
9+
/** Validate accounts before sign in using google cloud before sigin in syncronous function. */
10+
11+
export const beforeSignIn = new Auth()
12+
.functions()
13+
.beforeSignInHandler(
14+
async (user: UserRecord, context: AuthEventContext): Promise<UserEventUpdateRequest> => {
15+
/** The UserEventUpdate to save based on the signin results. */
16+
const event: UserEventUpdateRequest = {};
17+
18+
// If a user is able to reach this without a login credential being present, throw an auth error.
19+
// Note: This should not be possible, but it doesn't hurt to have this check in place.
20+
if (context.credential === undefined) {
21+
throw new https.HttpsError(
22+
'unauthenticated',
23+
`Cannot sign in as '${user.email}' without credential.`,
24+
);
25+
}
26+
27+
// When users sign in with github, we save the access token as a claim on the user object.
28+
if (context.credential.providerId === 'github.com') {
29+
event.customClaims = {...event.customClaims, githubToken: context.credential.accessToken};
30+
}
31+
32+
return event;
33+
},
34+
);

apps/account-functions/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export {beforeCreate} from './before-create';
2+
export {beforeSignIn} from './before-sign-in';

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
"firebase-functions": "^3.19.0",
113113
"firebase-tools": "^10.5.0",
114114
"font-color-contrast": "^11.1.0",
115+
"gcip-cloud-functions": "0.0.1",
115116
"git-raw-commits": "^2.0.10",
116117
"glob": "7.2.0",
117118
"husky": "^7.0.1",

yarn.lock

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ __metadata:
466466
firebase-functions: ^3.19.0
467467
firebase-tools: ^10.5.0
468468
font-color-contrast: ^11.1.0
469+
gcip-cloud-functions: 0.0.1
469470
git-raw-commits: ^2.0.10
470471
glob: 7.2.0
471472
husky: ^7.0.1
@@ -3727,7 +3728,7 @@ __metadata:
37273728
languageName: node
37283729
linkType: hard
37293730

3730-
"@types/cors@npm:^2.8.12, @types/cors@npm:^2.8.5":
3731+
"@types/cors@npm:^2.8.1, @types/cors@npm:^2.8.12, @types/cors@npm:^2.8.5":
37313732
version: 2.8.12
37323733
resolution: "@types/cors@npm:2.8.12"
37333734
checksum: 8c45f112c7d1d2d831b4b266f2e6ed33a1887a35dcbfe2a18b28370751fababb7cd045e745ef84a523c33a25932678097bf79afaa367c6cb3fa0daa7a6438257
@@ -3814,7 +3815,7 @@ __metadata:
38143815
languageName: node
38153816
linkType: hard
38163817

3817-
"@types/express@npm:*, @types/express@npm:^4.17.13":
3818+
"@types/express@npm:*, @types/express@npm:^4.11.1, @types/express@npm:^4.17.13":
38183819
version: 4.17.13
38193820
resolution: "@types/express@npm:4.17.13"
38203821
dependencies:
@@ -4038,6 +4039,13 @@ __metadata:
40384039
languageName: node
40394040
linkType: hard
40404041

4042+
"@types/node@npm:^8.0.53":
4043+
version: 8.10.66
4044+
resolution: "@types/node@npm:8.10.66"
4045+
checksum: c52039de862654a139abdc6a51de532a69dd80516ac35a959c3b3a2831ecbaaf065b0df5f9db943f5e28b544ebb9a891730d52b52f7a169b86a82bc060210000
4046+
languageName: node
4047+
linkType: hard
4048+
40414049
"@types/normalize-package-data@npm:^2.4.0":
40424050
version: 2.4.1
40434051
resolution: "@types/normalize-package-data@npm:2.4.1"
@@ -6329,7 +6337,7 @@ __metadata:
63296337
languageName: node
63306338
linkType: hard
63316339

6332-
"cors@npm:^2.8.5, cors@npm:~2.8.5":
6340+
"cors@npm:^2.8.4, cors@npm:^2.8.5, cors@npm:~2.8.5":
63336341
version: 2.8.5
63346342
resolution: "cors@npm:2.8.5"
63356343
dependencies:
@@ -7789,7 +7797,7 @@ __metadata:
77897797
languageName: node
77907798
linkType: hard
77917799

7792-
"express@npm:^4.16.4, express@npm:^4.17.1, express@npm:^4.17.3":
7800+
"express@npm:^4.16.2, express@npm:^4.16.4, express@npm:^4.17.1, express@npm:^4.17.3":
77937801
version: 4.17.3
77947802
resolution: "express@npm:4.17.3"
77957803
dependencies:
@@ -8500,6 +8508,21 @@ __metadata:
85008508
languageName: node
85018509
linkType: hard
85028510

8511+
"gcip-cloud-functions@npm:0.0.1":
8512+
version: 0.0.1
8513+
resolution: "gcip-cloud-functions@npm:0.0.1"
8514+
dependencies:
8515+
"@types/cors": ^2.8.1
8516+
"@types/express": ^4.11.1
8517+
"@types/node": ^8.0.53
8518+
cors: ^2.8.4
8519+
express: ^4.16.2
8520+
jsonwebtoken: 8.5.1
8521+
node-forge: ^0.10.0
8522+
checksum: 3cd07dbafa51ba0ba7d9f8efc50c25f4c08c85c3750fb156af590be209e47efd9d541e892fcfeba12432465d134984b14bc177369eb0c6b6a3587c9c9f851622
8523+
languageName: node
8524+
linkType: hard
8525+
85038526
"gcp-metadata@npm:^4.2.0":
85048527
version: 4.3.1
85058528
resolution: "gcp-metadata@npm:4.3.1"
@@ -10258,7 +10281,7 @@ __metadata:
1025810281
languageName: node
1025910282
linkType: hard
1026010283

10261-
"jsonwebtoken@npm:^8.5.1":
10284+
"jsonwebtoken@npm:8.5.1, jsonwebtoken@npm:^8.5.1":
1026210285
version: 8.5.1
1026310286
resolution: "jsonwebtoken@npm:8.5.1"
1026410287
dependencies:
@@ -11725,6 +11748,13 @@ __metadata:
1172511748
languageName: node
1172611749
linkType: hard
1172711750

11751+
"node-forge@npm:^0.10.0":
11752+
version: 0.10.0
11753+
resolution: "node-forge@npm:0.10.0"
11754+
checksum: 5aa6dc9922e424a20ef101d2f517418e2bc9cfc0255dd22e0701c0fad1568445f510ee67f6f3fcdf085812c4ca1b847b8ba45683b34776828e41f5c1794e42e1
11755+
languageName: node
11756+
linkType: hard
11757+
1172811758
"node-forge@npm:^1, node-forge@npm:^1.0.0":
1172911759
version: 1.3.1
1173011760
resolution: "node-forge@npm:1.3.1"

0 commit comments

Comments
 (0)