Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 119 additions & 11 deletions spec/common/providers/identity.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import * as identity from "../../../src/common/providers/identity";

const EVENT = "EVENT_TYPE";
const now = new Date();
const TEST_NAME = "John Doe";
const ALLOW = "ALLOW";
const BLOCK = "BLOCK";

describe("identity", () => {
describe("userRecordConstructor", () => {
Expand Down Expand Up @@ -232,14 +235,14 @@ describe("identity", () => {
describe("parseProviderData", () => {
const decodedUserInfo = {
provider_id: "google.com",
display_name: "John Doe",
display_name: TEST_NAME,
photo_url: "https://lh3.googleusercontent.com/1234567890/photo.jpg",
uid: "1234567890",
email: "[email protected]",
};
const userInfo = {
providerId: "google.com",
displayName: "John Doe",
displayName: TEST_NAME,
photoURL: "https://lh3.googleusercontent.com/1234567890/photo.jpg",
uid: "1234567890",
email: "[email protected]",
Expand Down Expand Up @@ -340,12 +343,12 @@ describe("identity", () => {
uid: "abcdefghijklmnopqrstuvwxyz",
email: "[email protected]",
email_verified: true,
display_name: "John Doe",
display_name: TEST_NAME,
phone_number: "+11234567890",
provider_data: [
{
provider_id: "google.com",
display_name: "John Doe",
display_name: TEST_NAME,
photo_url: "https://lh3.googleusercontent.com/1234567890/photo.jpg",
email: "[email protected]",
uid: "1234567890",
Expand All @@ -366,7 +369,7 @@ describe("identity", () => {
provider_id: "password",
email: "[email protected]",
uid: "[email protected]",
display_name: "John Doe",
display_name: TEST_NAME,
},
],
password_hash: "passwordHash",
Expand Down Expand Up @@ -407,11 +410,11 @@ describe("identity", () => {
phoneNumber: "+11234567890",
emailVerified: true,
disabled: false,
displayName: "John Doe",
displayName: TEST_NAME,
providerData: [
{
providerId: "google.com",
displayName: "John Doe",
displayName: TEST_NAME,
photoURL: "https://lh3.googleusercontent.com/1234567890/photo.jpg",
email: "[email protected]",
uid: "1234567890",
Expand All @@ -435,7 +438,7 @@ describe("identity", () => {
},
{
providerId: "password",
displayName: "John Doe",
displayName: TEST_NAME,
photoURL: undefined,
email: "[email protected]",
uid: "[email protected]",
Expand Down Expand Up @@ -489,8 +492,9 @@ describe("identity", () => {
});

describe("parseAuthEventContext", () => {
const TEST_RECAPTCHA_SCORE = 0.9;
const rawUserInfo = {
name: "John Doe",
name: TEST_NAME,
granted_scopes:
"openid https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile",
id: "123456789",
Expand All @@ -516,13 +520,15 @@ describe("identity", () => {
user_agent: "USER_AGENT",
locale: "en",
raw_user_info: JSON.stringify(rawUserInfo),
recaptcha_score: TEST_RECAPTCHA_SCORE,
};
const context = {
locale: "en",
ipAddress: "1.2.3.4",
userAgent: "USER_AGENT",
eventId: "EVENT_ID",
eventType: EVENT,
emailType: undefined,
authType: "UNAUTHENTICATED",
resource: {
service: "identitytoolkit.googleapis.com",
Expand All @@ -534,6 +540,8 @@ describe("identity", () => {
profile: rawUserInfo,
username: undefined,
isNewUser: false,
recaptchaScore: TEST_RECAPTCHA_SCORE,
email: undefined,
},
credential: null,
params: {},
Expand Down Expand Up @@ -563,13 +571,15 @@ describe("identity", () => {
oauth_refresh_token: "REFRESH_TOKEN",
oauth_token_secret: "OAUTH_TOKEN_SECRET",
oauth_expires_in: 3600,
recaptcha_score: TEST_RECAPTCHA_SCORE,
};
const context = {
locale: "en",
ipAddress: "1.2.3.4",
userAgent: "USER_AGENT",
eventId: "EVENT_ID",
eventType: "providers/cloud.auth/eventTypes/user.beforeSignIn:password",
emailType: undefined,
authType: "UNAUTHENTICATED",
resource: {
service: "identitytoolkit.googleapis.com",
Expand All @@ -581,6 +591,8 @@ describe("identity", () => {
profile: rawUserInfo,
username: undefined,
isNewUser: false,
recaptchaScore: TEST_RECAPTCHA_SCORE,
email: undefined,
},
credential: {
claims: undefined,
Expand Down Expand Up @@ -619,14 +631,14 @@ describe("identity", () => {
uid: "abcdefghijklmnopqrstuvwxyz",
email: "[email protected]",
email_verified: true,
display_name: "John Doe",
display_name: TEST_NAME,
phone_number: "+11234567890",
provider_data: [
{
provider_id: "oidc.provider",
email: "[email protected]",
uid: "[email protected]",
display_name: "John Doe",
display_name: TEST_NAME,
},
],
photo_url: "https://lh3.googleusercontent.com/1234567890/photo.jpg",
Expand All @@ -647,13 +659,15 @@ describe("identity", () => {
oauth_token_secret: "OAUTH_TOKEN_SECRET",
oauth_expires_in: 3600,
raw_user_info: JSON.stringify(rawUserInfo),
recaptcha_score: TEST_RECAPTCHA_SCORE,
};
const context = {
locale: "en",
ipAddress: "1.2.3.4",
userAgent: "USER_AGENT",
eventId: "EVENT_ID",
eventType: "providers/cloud.auth/eventTypes/user.beforeCreate:oidc.provider",
emailType: undefined,
authType: "USER",
resource: {
service: "identitytoolkit.googleapis.com",
Expand All @@ -665,6 +679,8 @@ describe("identity", () => {
providerId: "oidc.provider",
profile: rawUserInfo,
isNewUser: true,
recaptchaScore: TEST_RECAPTCHA_SCORE,
email: undefined,
},
credential: {
claims: undefined,
Expand All @@ -681,6 +697,50 @@ describe("identity", () => {

expect(identity.parseAuthEventContext(decodedJwt, "project-id", time)).to.deep.equal(context);
});

it("should parse a beforeSendEmail event", () => {
const time = now.getTime();
const decodedJwt = {
iss: "https://securetoken.google.com/project_id",
aud: "https://us-east1-project_id.cloudfunctions.net/function-1",
iat: 1,
exp: 60 * 60 + 1,
event_id: "EVENT_ID",
event_type: "beforeSendEmail",
user_agent: "USER_AGENT",
ip_address: "1.2.3.4",
locale: "en",
recaptcha_score: TEST_RECAPTCHA_SCORE,
email_type: "RESET_PASSWORD",
email: "[email protected]",
};
const context = {
locale: "en",
ipAddress: "1.2.3.4",
userAgent: "USER_AGENT",
eventId: "EVENT_ID",
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
emailType: "RESET_PASSWORD",
authType: "UNAUTHENTICATED",
resource: {
service: "identitytoolkit.googleapis.com",
name: "projects/project-id",
},
timestamp: new Date(1000).toUTCString(),
additionalUserInfo: {
isNewUser: false,
profile: undefined,
providerId: undefined,
username: undefined,
recaptchaScore: TEST_RECAPTCHA_SCORE,
email: "[email protected]",
},
credential: null,
params: {},
};

expect(identity.parseAuthEventContext(decodedJwt, "project-id", time)).to.deep.equal(context);
});
});

describe("validateAuthResponse", () => {
Expand Down Expand Up @@ -762,4 +822,52 @@ describe("identity", () => {
);
});
});

describe("generateResponsePayload", () => {
const DISPLAY_NAME_FIELD = "displayName";
const TEST_RESPONSE = {
displayName: TEST_NAME,
recaptchaActionOverride: BLOCK,
} as identity.BeforeCreateResponse;

const EXPECT_PAYLOAD = {
userRecord: { displayName: TEST_NAME, updateMask: DISPLAY_NAME_FIELD },
recaptchaActionOverride: BLOCK,
};

const TEST_RESPONSE_RECAPTCHA_ALLOW = {
recaptchaActionOverride: ALLOW,
} as identity.BeforeCreateResponse;

const EXPECT_PAYLOAD_RECAPTCHA_ALLOW = {
recaptchaActionOverride: ALLOW,
};

const TEST_RESPONSE_RECAPTCHA_UNDEFINED = {
displayName: TEST_NAME,
} as identity.BeforeSignInResponse;

const EXPECT_PAYLOAD_UNDEFINED = {
userRecord: { displayName: TEST_NAME, updateMask: DISPLAY_NAME_FIELD },
};
it("should return empty object on undefined response", () => {
expect(identity.generateResponsePayload()).to.eql({});
});

it("should exclude recaptchaActionOverride field from updateMask", () => {
expect(identity.generateResponsePayload(TEST_RESPONSE)).to.deep.equal(EXPECT_PAYLOAD);
});

it("should return recaptchaActionOverride when it is true on response", () => {
expect(identity.generateResponsePayload(TEST_RESPONSE_RECAPTCHA_ALLOW)).to.deep.equal(
EXPECT_PAYLOAD_RECAPTCHA_ALLOW
);
});

it("should not return recaptchaActionOverride if undefined", () => {
const payload = identity.generateResponsePayload(TEST_RESPONSE_RECAPTCHA_UNDEFINED);
expect(payload.hasOwnProperty("recaptchaActionOverride")).to.be.false;
expect(payload).to.deep.equal(EXPECT_PAYLOAD_UNDEFINED);
});
});
});
90 changes: 90 additions & 0 deletions spec/v1/providers/auth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,96 @@ describe("Auth Functions", () => {
});
});

describe("beforeEmail", () => {
it("should create function without options", () => {
const fn = auth.user().beforeEmail(() => Promise.resolve());

expect(fn.__trigger).to.deep.equal({
labels: {},
blockingTrigger: {
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
options: {
accessToken: false,
idToken: false,
refreshToken: false,
},
},
});
expect(fn.__endpoint).to.deep.equal({
...MINIMAL_V1_ENDPOINT,
platform: "gcfv1",
labels: {},
blockingTrigger: {
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
options: {
accessToken: false,
idToken: false,
refreshToken: false,
},
},
});
expect(fn.__requiredAPIs).to.deep.equal([
{
api: "identitytoolkit.googleapis.com",
reason: "Needed for auth blocking functions",
},
]);
});

it("should create the function with options", () => {
const fn = functions
.region("us-east1")
.runWith({
timeoutSeconds: 90,
memory: "256MB",
})
.auth.user({
blockingOptions: {
accessToken: true,
refreshToken: false,
},
})
.beforeEmail(() => Promise.resolve());

expect(fn.__trigger).to.deep.equal({
labels: {},
regions: ["us-east1"],
availableMemoryMb: 256,
timeout: "90s",
blockingTrigger: {
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
options: {
accessToken: true,
idToken: false,
refreshToken: false,
},
},
});
expect(fn.__endpoint).to.deep.equal({
...MINIMAL_V1_ENDPOINT,
platform: "gcfv1",
labels: {},
region: ["us-east1"],
availableMemoryMb: 256,
timeoutSeconds: 90,
blockingTrigger: {
eventType: "providers/cloud.auth/eventTypes/user.beforeSendEmail",
options: {
accessToken: true,
idToken: false,
refreshToken: false,
},
},
});
expect(fn.__requiredAPIs).to.deep.equal([
{
api: "identitytoolkit.googleapis.com",
reason: "Needed for auth blocking functions",
},
]);
});
});

describe("#_dataConstructor", () => {
let cloudFunctionDelete: CloudFunction<UserRecord>;

Expand Down
Loading