diff --git a/Node/quickstarts/auth-blocking-functions/functions/index.js b/Node/quickstarts/auth-blocking-functions/functions/index.js index d6ef1c4beb..0d0660e95b 100644 --- a/Node/quickstarts/auth-blocking-functions/functions/index.js +++ b/Node/quickstarts/auth-blocking-functions/functions/index.js @@ -17,9 +17,12 @@ const { beforeUserCreated, beforeUserSignedIn, + beforeEmailSent, + beforeSmsSent, HttpsError, } = require("firebase-functions/identity"); -const {admin} = require("firebase-admin"); +const {defineString} = require("firebase-functions/params"); +const admin = require("firebase-admin"); admin.initializeApp(); const db = admin.firestore(); @@ -27,7 +30,7 @@ const db = admin.firestore(); // [START v2ValidateNewUser] // [START v2beforeCreateFunctionTrigger] // Block account creation with any non-acme email address. -exports.validatenewuser = beforeUserCreated((event) => { +exports.validateNewUser = beforeUserCreated((event) => { // [END v2beforeCreateFunctionTrigger] // [START v2readUserData] // User data passed in from the CloudEvent. @@ -47,7 +50,7 @@ exports.validatenewuser = beforeUserCreated((event) => { // [START v2CheckForBan] // [START v2beforeSignInFunctionTrigger] // Block account sign in with any banned account. -exports.checkforban = beforeUserSignedIn(async (event) => { +exports.checkForBan = beforeUserSignedIn(async (event) => { // [END v2beforeSignInFunctionTrigger] // [START v2readEmailData] // Email passed from the CloudEvent. @@ -68,3 +71,61 @@ exports.checkforban = beforeUserSignedIn(async (event) => { // [END v2bannedHttpsError] }); // [START v2CheckForBan] + +// [START v2CheckEmailDomain] +// [START v2beforeEmailSentFunctionTrigger] +// Block email sending with any non-acme email address. +exports.checkEmailDomain = beforeEmailSent((event) => { + // [END v2beforeEmailSentFunctionTrigger] + // [START v2readEmailUser] + // Email passed in from the CloudEvent. + const email = event.data?.email || event.additionalUserInfo?.email; + // [END v2readEmailUser] + + // [START v2emailHttpsError] + // Only users of a specific domain can receive emails. + if (!email) { + // Throw an HttpsError so that Firebase Auth rejects the email sending. + throw new HttpsError("invalid-argument", + "No email was found in the CloudEvent"); + } + if (!email.endsWith("@acme.com")) { + throw new HttpsError("permission-denied", + "Only users from the acme.com domain can " + + "authenticate"); + } + // [END v2emailHttpsError] +}); +// [END v2CheckEmailDomain] + +// [START v2CheckPhoneNumber] +// [START v2beforeSmsSentFunctionTrigger] + +const intlPrefixNumber = defineString("INTERNATIONAL_PREFIX_NUMBER", { + default: "+1", + description: "The country code that we restrict sending to.", +}); +// Block SMS sending with any non-US phone number. +exports.checkPhoneNumber = beforeSmsSent((event) => { + // [END v2beforeSmsSentFunctionTrigger] + // [START v2readSmsUser] + // Phone number passed from the CloudEvent. + const phoneNumber = event.data?.phoneNumber || + event.additionalUserInfo?.phoneNumber; + // [END v2readSmsUser] + + // [START v2smsHttpsError] + if (!phoneNumber) { + // Throw an HttpsError so that Firebase Auth rejects the SMS sending. + throw new HttpsError("invalid-argument", + "No phone number was found in the CloudEvent"); + } + + // Only users of a specific region can receive SMS. + if (!phoneNumber.startsWith(intlPrefixNumber.value())) { + // Throw an HttpsError so that Firebase Auth rejects the SMS sending. + throw new HttpsError("invalid-argument", "Unauthorized phone number"); + } + // [END v2smsHttpsError] +}); +// [END v2CheckPhoneNumber]