Skip to content

Commit 0d63ade

Browse files
committed
Merge branch 'master' into ss-admin-auth-features
2 parents 435a151 + f1869ee commit 0d63ade

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+12011
-35131
lines changed

.github/workflows/node.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ jobs:
1313
strategy:
1414
matrix:
1515
node-version:
16-
- 10.x
17-
- 12.x
16+
- 18.x
17+
- 20.x
1818
steps:
19-
- uses: actions/checkout@v1
20-
- uses: actions/setup-node@v1
19+
- uses: actions/checkout@v3
20+
- uses: actions/setup-node@v3
2121
with:
2222
node-version: ${{ matrix.node-version }}
2323

2424
- name: Cache npm
25-
uses: actions/cache@v1
25+
uses: actions/cache@v3
2626
with:
2727
path: ~/.npm
2828
key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }}

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,8 @@ firebase-debug.log
1313

1414
.idea/
1515

16+
# pnpm manages deps in the pnpm-lock.yaml file instead
17+
**/package-lock.json
18+
# keep the root package-lock so that tools are consistent
19+
!/package-lock.json
20+

auth/create_custom_tokens.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
'use strict';
2-
const admin = require('firebase-admin');
2+
const { initializeApp } = require('firebase-admin/app');
3+
const { getAuth } = require('firebase-admin/auth');
34

45
// Initialize the Admin app with the default appication credentials
56
// [START initialize_sdk_with_default_config]
6-
admin.initializeApp();
7+
initializeApp();
78
// [END initialize_sdk_with_default_config]
89

910
// Initialize the Admin app by providing a service accoune key
1011
// [START initialize_sdk_with_service_account_id]
11-
admin.initializeApp({
12+
initializeApp({
1213
serviceAccountId: '[email protected]',
1314
});
1415
// [END initialize_sdk_with_service_account_id]
1516

1617
// [START custom_token]
1718
const uid = 'some-uid';
1819

19-
admin
20-
.auth()
20+
getAuth()
2121
.createCustomToken(uid)
2222
.then((customToken) => {
2323
// Send token back to client
@@ -33,8 +33,7 @@ const additionalClaims = {
3333
premiumAccount: true,
3434
};
3535

36-
admin
37-
.auth()
36+
getAuth()
3837
.createCustomToken(userId, additionalClaims)
3938
.then((customToken) => {
4039
// Send token back to client

auth/custom_claims.js

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
'use strict';
2-
const admin = require('firebase-admin');
3-
admin.initializeApp();
2+
const { initializeApp } = require('firebase-admin/app');
3+
const { getAuth } = require('firebase-admin/auth');
4+
const { getDatabase } = require('firebase-admin/database');
5+
initializeApp();
6+
7+
const express = require('express');
48

59
const uid = 'firebaseUserId123';
610
const idToken = 'some-invalid-token';
711

812
// [START set_custom_user_claims]
913
// Set admin privilege on the user corresponding to uid.
1014

11-
admin
12-
.auth()
15+
getAuth()
1316
.setCustomUserClaims(uid, { admin: true })
1417
.then(() => {
1518
// The new custom claims will propagate to the user's ID token the
@@ -19,8 +22,7 @@ admin
1922

2023
// [START verify_custom_claims]
2124
// Verify the ID token first.
22-
admin
23-
.auth()
25+
getAuth()
2426
.verifyIdToken(idToken)
2527
.then((claims) => {
2628
if (claims.admin === true) {
@@ -31,8 +33,7 @@ admin
3133

3234
// [START read_custom_user_claims]
3335
// Lookup the user associated with the specified uid.
34-
admin
35-
.auth()
36+
getAuth()
3637
.getUser(uid)
3738
.then((userRecord) => {
3839
// The claims can be accessed on the user record.
@@ -41,15 +42,14 @@ admin
4142
// [END read_custom_user_claims]
4243

4344
// [START set_custom_user_claims_script]
44-
admin
45-
.auth()
45+
getAuth()
4646
.getUserByEmail('[email protected]')
4747
.then((user) => {
4848
// Confirm user is verified.
4949
if (user.emailVerified) {
5050
// Add custom claims for additional privileges.
5151
// This will be picked up by the user on token refresh or next sign in on new device.
52-
return admin.auth().setCustomUserClaims(user.uid, {
52+
return getAuth().setCustomUserClaims(user.uid, {
5353
admin: true,
5454
});
5555
}
@@ -60,8 +60,7 @@ admin
6060
// [END set_custom_user_claims_script]
6161

6262
// [START set_custom_user_claims_incremental]
63-
admin
64-
.auth()
63+
getAuth()
6564
.getUserByEmail('[email protected]')
6665
.then((user) => {
6766
// Add incremental custom claim without overwriting existing claims.
@@ -70,10 +69,45 @@ admin
7069
// Add level.
7170
currentCustomClaims['accessLevel'] = 10;
7271
// Add custom claims for additional privileges.
73-
return admin.auth().setCustomUserClaims(user.uid, currentCustomClaims);
72+
return getAuth().setCustomUserClaims(user.uid, currentCustomClaims);
7473
}
7574
})
7675
.catch((error) => {
7776
console.log(error);
7877
});
7978
// [END set_custom_user_claims_incremental]
79+
80+
function customClaimsServer() {
81+
const app = express();
82+
83+
// [START auth_custom_claims_server]
84+
app.post('/setCustomClaims', async (req, res) => {
85+
// Get the ID token passed.
86+
const idToken = req.body.idToken;
87+
88+
// Verify the ID token and decode its payload.
89+
const claims = await getAuth().verifyIdToken(idToken);
90+
91+
// Verify user is eligible for additional privileges.
92+
if (
93+
typeof claims.email !== 'undefined' &&
94+
typeof claims.email_verified !== 'undefined' &&
95+
claims.email_verified &&
96+
claims.email.endsWith('@admin.example.com')
97+
) {
98+
// Add custom claims for additional privileges.
99+
await getAuth().setCustomUserClaims(claims.sub, {
100+
admin: true
101+
});
102+
103+
// Tell client to refresh token on user.
104+
res.end(JSON.stringify({
105+
status: 'success'
106+
}));
107+
} else {
108+
// Return nothing.
109+
res.end(JSON.stringify({ status: 'ineligible' }));
110+
}
111+
});
112+
// [END auth_custom_claims_server]
113+
}

auth/email_action_links.js

Lines changed: 39 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
2-
const admin = require('firebase-admin');
3-
admin.initializeApp();
2+
const { initializeApp } = require('firebase-admin/app');
3+
const { getAuth } = require('firebase-admin/auth');
4+
initializeApp();
45

56
// [START init_action_code_settings]
67
const actionCodeSettings = {
@@ -17,73 +18,59 @@ const actionCodeSettings = {
1718
installApp: true,
1819
minimumVersion: '12',
1920
},
20-
// FDL custom domain.
21-
dynamicLinkDomain: 'coolapp.page.link',
21+
// The domain must be configured in Firebase Hosting and owned by the project.
22+
linkDomain: 'custom-domain.com',
2223
};
2324
// [END init_action_code_settings]
2425

2526
// [START password_reset_link]
2627
// Admin SDK API to generate the password reset link.
2728
const userEmail = '[email protected]';
28-
admin
29-
.auth()
29+
getAuth()
3030
.generatePasswordResetLink(userEmail, actionCodeSettings)
3131
.then((link) => {
3232
// Construct password reset email template, embed the link and send
3333
// using custom SMTP server.
34-
return sendCustomPasswordResetEmail(email, displayName, link);
34+
return sendCustomPasswordResetEmail(userEmail, displayName, link);
3535
})
3636
.catch((error) => {
3737
// Some error occurred.
3838
});
3939
// [END password_reset_link]
4040

41-
// [START email_verification_link]
42-
// Admin SDK API to generate the password reset link.
43-
const email = '[email protected]';
44-
admin
45-
.auth()
46-
.generatePasswordResetLink(email, actionCodeSettings)
47-
.then((link) => {
48-
// Construct password reset email template, embed the link and send
49-
// using custom SMTP server.
50-
return sendCustomPasswordResetEmail(email, displayName, link);
51-
})
52-
.catch((error) => {
53-
// Some error occurred.
54-
});
55-
56-
// [START email_verification_link]
57-
// Admin SDK API to generate the email verification link.
58-
const useremail = '[email protected]';
59-
admin
60-
.auth()
61-
.generateEmailVerificationLink(useremail, actionCodeSettings)
62-
.then((link) => {
63-
// Construct email verification template, embed the link and send
64-
// using custom SMTP server.
65-
return sendCustomVerificationEmail(useremail, displayName, link);
66-
})
67-
.catch((error) => {
68-
// Some error occurred.
69-
});
70-
// [END email_verification_link]
41+
function emailVerificationLink() {
42+
// [START email_verification_link]
43+
// Admin SDK API to generate the email verification link.
44+
const useremail = '[email protected]';
45+
getAuth()
46+
.generateEmailVerificationLink(useremail, actionCodeSettings)
47+
.then((link) => {
48+
// Construct email verification template, embed the link and send
49+
// using custom SMTP server.
50+
return sendCustomVerificationEmail(useremail, displayName, link);
51+
})
52+
.catch((error) => {
53+
// Some error occurred.
54+
});
55+
// [END email_verification_link]
56+
}
7157

72-
// [START sign_in_with_email_link]
73-
// Admin SDK API to generate the sign in with email link.
74-
const usremail = '[email protected]';
75-
admin
76-
.auth()
77-
.generateSignInWithEmailLink(usremail, actionCodeSettings)
78-
.then((link) => {
79-
// Construct sign-in with email link template, embed the link and
80-
// send using custom SMTP server.
81-
return sendSignInEmail(usremail, displayName, link);
82-
})
83-
.catch((error) => {
84-
// Some error occurred.
85-
});
86-
// [END sign_in_with_email_link]
58+
function signInWithEmailLink() {
59+
// [START sign_in_with_email_link]
60+
// Admin SDK API to generate the sign in with email link.
61+
const useremail = '[email protected]';
62+
getAuth()
63+
.generateSignInWithEmailLink(useremail, actionCodeSettings)
64+
.then((link) => {
65+
// Construct sign-in with email link template, embed the link and
66+
// send using custom SMTP server.
67+
return sendSignInEmail(useremail, displayName, link);
68+
})
69+
.catch((error) => {
70+
// Some error occurred.
71+
});
72+
// [END sign_in_with_email_link]
73+
}
8774

8875
let displayName;
8976
const sendSignInEmail = (...args) => {

auth/functions/custom_claims.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// [START auth_custom_claims_cloud_function]
2+
const functions = require('firebase-functions');
3+
const { initializeApp } = require('firebase-admin/app');
4+
const { getAuth } = require('firebase-admin/auth');
5+
const { getDatabase } = require('firebase-admin/database');
6+
7+
initializeApp();
8+
9+
// On sign up.
10+
exports.processSignUp = functions.auth.user().onCreate(async (user) => {
11+
// Check if user meets role criteria.
12+
if (
13+
user.email &&
14+
user.email.endsWith('@admin.example.com') &&
15+
user.emailVerified
16+
) {
17+
const customClaims = {
18+
admin: true,
19+
accessLevel: 9
20+
};
21+
22+
try {
23+
// Set custom user claims on this newly created user.
24+
await getAuth().setCustomUserClaims(user.uid, customClaims);
25+
26+
// Update real-time database to notify client to force refresh.
27+
const metadataRef = getDatabase().ref('metadata/' + user.uid);
28+
29+
// Set the refresh time to the current UTC timestamp.
30+
// This will be captured on the client to force a token refresh.
31+
await metadataRef.set({refreshTime: new Date().getTime()});
32+
} catch (error) {
33+
console.log(error);
34+
}
35+
}
36+
});
37+
// [END auth_custom_claims_cloud_function]

auth/functions/package.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "auth-functions",
3+
"version": "1.0.0",
4+
"main": "index.js",
5+
"author": "",
6+
"license": "Apache-2.0",
7+
"scripts": {
8+
"compile": "cp ../../tsconfig.template.json ./tsconfig.json && tsc"
9+
},
10+
"dependencies": {
11+
"firebase-admin": "^11.9.0",
12+
"firebase-functions": "^4.4.0"
13+
}
14+
}

auth/get_service_account_tokens.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
*/
1616
'use strict';
1717
// [START get_service_account_tokens]
18-
const admin = require('firebase-admin');
18+
const { cert } = require('firebase-admin/app');
1919

2020
const serviceAccount = require('./path/to/serviceAccountKey.json');
21-
const credential = admin.credential.cert(serviceAccount);
21+
const credential = cert(serviceAccount);
2222

2323
credential.getAccessToken().then((accessTokenInfo) => {
2424
const accessToken = accessTokenInfo.access_token;

0 commit comments

Comments
 (0)