Skip to content
Merged
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
4,730 changes: 2,173 additions & 2,557 deletions firestore-bigquery-export/functions/package-lock.json

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions firestore-send-email/POSTINSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,28 @@ admin

See the [official documentation](https://firebase.google.com/docs/extensions/official/firestore-send-email) for information on using this extension, including advanced use cases such as using Handlebars templates and managing email delivery status.

#### Firestore-Send-Email: SendGrid Categories

When using SendGrid (`SMTP_CONNECTION_URI` includes `sendgrid.net`), you can assign categories to your emails.

## Example JSON with Categories:
```json
{
"to": ["[email protected]"],
"categories": ["Example_Category"],
"message": {
"subject": "Test Email with Categories",
"text": "This is a test email to see if categories work.",
"html": "<strong>This is a test email to see if categories work.</strong>"
}
}
```

Add this document to the Firestore mail collection to send categorized emails.

For more details, see the [SendGrid Categories documentation](https://docs.sendgrid.com/ui/sending-email/categories).


### Monitoring

As a best practice, you can [monitor the activity](https://firebase.google.com/docs/extensions/manage-installed-extensions#monitor) of your installed extension, including checks on its health, usage, and logs.
Expand Down
21 changes: 21 additions & 0 deletions firestore-send-email/PREINSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,27 @@ You can also optionally configure this extension to render emails using [Handleb

When you configure this extension, you'll need to supply your **SMTP credentials for mail delivery**. Note that this extension is for use with bulk email service providers, like SendGrid, Mailgun, etc.

#### Firestore-Send-Email: SendGrid Categories

When using SendGrid (`SMTP_CONNECTION_URI` includes `sendgrid.net`), you can assign categories to your emails.

## Example JSON with Categories:
```json
{
"to": ["[email protected]"],
"categories": ["Example_Category"],
"message": {
"subject": "Test Email with Categories",
"text": "This is a test email to see if categories work.",
"html": "<strong>This is a test email to see if categories work.</strong>"
}
}
```

Add this document to the Firestore mail collection to send categorized emails.

For more details, see the [SendGrid Categories documentation](https://docs.sendgrid.com/ui/sending-email/categories).

#### Setup Google App Passwords

**Google** no longer allows **Gmail** users to use their own passwords to authorize third-party apps and services. Instead, you have to use the [Sign in with App Passwords](https://support.google.com/accounts/answer/185833) service to generate a special password for each app you want to authorize. To do so:
Expand Down
21 changes: 21 additions & 0 deletions firestore-send-email/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,27 @@ You can also optionally configure this extension to render emails using [Handleb

When you configure this extension, you'll need to supply your **SMTP credentials for mail delivery**. Note that this extension is for use with bulk email service providers, like SendGrid, Mailgun, etc.

#### Firestore-Send-Email: SendGrid Categories

When using SendGrid (`SMTP_CONNECTION_URI` includes `sendgrid.net`), you can assign categories to your emails.

## Example JSON with Categories:
```json
{
"to": ["[email protected]"],
"categories": ["Example_Category"],
"message": {
"subject": "Test Email with Categories",
"text": "This is a test email to see if categories work.",
"html": "<strong>This is a test email to see if categories work.</strong>"
}
}
```

Add this document to the Firestore mail collection to send categorized emails.

For more details, see the [SendGrid Categories documentation](https://docs.sendgrid.com/ui/sending-email/categories).

#### Setup Google App Passwords

**Google** no longer allows **Gmail** users to use their own passwords to authorize third-party apps and services. Instead, you have to use the [Sign in with App Passwords](https://support.google.com/accounts/answer/185833) service to generate a special password for each app you want to authorize. To do so:
Expand Down
87 changes: 42 additions & 45 deletions firestore-send-email/functions/__tests__/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Mail = require("nodemailer/lib/mailer");
const { logger } = require("firebase-functions");

import { setSmtpCredentials } from "../src/helpers";
import { setSmtpCredentials, isSendGrid } from "../src/helpers";
import { Config } from "../src/types";

const consoleLogSpy = jest.spyOn(logger, "warn").mockImplementation();
Expand All @@ -11,7 +11,7 @@ const regex = new RegExp(
"^(smtp[s]*://(.*?(:[^:@]*)?@)?[^:@]+:[0-9]+(\\?[^ ]*)?)$"
);

describe("set server credentials helper function", () => {
describe("setSmtpCredentials function", () => {
test("return smtpServerDomain credentials with new password", () => {
const config: Config = {
smtpConnectionUri:
Expand All @@ -32,26 +32,7 @@ describe("set server credentials helper function", () => {
expect(regex.test(config.smtpConnectionUri)).toBe(true);
});

test("return smtpServerDomain credentials with new password (old deleted)", () => {
const config: Config = {
smtpConnectionUri: "smtps://[email protected]@smtp.gmail.com:465",
smtpPassword: "sec#:@ret-password",
location: "",
mailCollection: "",
defaultFrom: "",
};
const credentials = setSmtpCredentials(config);
expect(credentials).toBeInstanceOf(Mail);
expect(credentials.options.port).toBe(465);
expect(credentials.options.host).toBe("smtp.gmail.com");
expect(credentials.options.auth.pass).toBe(config.smtpPassword);
expect(credentials.options.secure).toBe(true);

// The regex should match the smtpConnectionUri, it should be valid
expect(regex.test(config.smtpConnectionUri)).toBe(true);
});

test("return smtpConnectionUri credentials with old password", () => {
test("return smtpServerDomain credentials with old password", () => {
const config: Config = {
smtpConnectionUri:
"smtps://[email protected]:[email protected]:465",
Expand Down Expand Up @@ -130,7 +111,7 @@ describe("set server credentials helper function", () => {
expect(regex.test(config.smtpConnectionUri)).toBe(true);
});

test("return valid smtpConnectionUri credentials with special chars in password config", () => {
test("return valid smtpConnectionUri credentials with valid special chars in password", () => {
const config: Config = {
smtpConnectionUri:
"smtp://[email protected]@smtp.gmail.com:465?pool=true&service=gmail",
Expand Down Expand Up @@ -176,7 +157,7 @@ describe("set server credentials helper function", () => {
expect(regex.test(config.smtpConnectionUri)).toBe(true);
});

test("return invalid smtpConnectionUri credentials with invalid special chars in connectionUri password", () => {
test("throw error for invalid smtpConnectionUri", () => {
const config: Config = {
smtpConnectionUri:
"smtp://[email protected]:4,h?dhuNTbv9zMrP4&7&7%*[email protected]:465?pool=true&service=gmail",
Expand All @@ -185,48 +166,64 @@ describe("set server credentials helper function", () => {
defaultFrom: "",
};

// Expect an error to be thrown
expect(() => setSmtpCredentials(config)).toThrow(Error);

expect(consoleLogSpy).toBeCalledWith(
"Invalid URI: please reconfigure with a valid SMTP connection URI"
);
});
test("return valid smtpConnectionUri credentials with correct seprator", () => {
});

describe("isSendGrid function", () => {
test("return true for SendGrid SMTP URI", () => {
const config: Config = {
smtpConnectionUri:
"smtp://[email protected]:4,h?dhuNTbv9zMrP4&7&7%*[email protected]:465?pool=true&service=gmail",
smtpConnectionUri: "smtps://[email protected]:465",
location: "",
mailCollection: "",
defaultFrom: "",
};

expect(regex.test(config.smtpConnectionUri)).toBe(true);
expect(isSendGrid(config)).toBe(true);
});

test("return invalid smtpConnectionUri credentials with invalid seprator", () => {
test("return false for non-SendGrid SMTP URI", () => {
const config: Config = {
smtpConnectionUri:
"smtp://[email protected]:4,h?dhuNTbv9zMrP4&7&7%*3:smtp.gmail.com:465?pool=true&service=gmail",
"smtps://[email protected]:secret-password@smtp.gmail.com:465",
location: "",
mailCollection: "",
defaultFrom: "",
};

expect(regex.test(config.smtpConnectionUri)).toBe(false);
expect(isSendGrid(config)).toBe(false);
});
});

/* Test removed due to the new SendGrid transporter logic - see setSendGridTransport()
test("return a SendGrid transporter if the host is smtp.sendgrid.net", () => {
const config: Config = {
smtpConnectionUri: "smtps://apikey@smtp.sendgrid.net:465",
location: "",
mailCollection: "",
defaultFrom: "",
};
test("return invalid smtpConnectionUri credentials with invalid separator", () => {
const config: Config = {
smtpConnectionUri:
"smtp://[email protected]:4,h?dhuNTbv9zMrP4&7&7%*3:smtp.gmail.com:465?pool=true&service=gmail",
location: "",
mailCollection: "",
defaultFrom: "",
};

const credentials = setSmtpCredentials(config);
expect(credentials.transporter.name === "nodemailer-sendgrid").toBe(true);
});
*/
expect(regex.test(config.smtpConnectionUri)).toBe(false);
});

test("correctly detects SendGrid SMTP URI", () => {
const config: Config = {
smtpConnectionUri: "smtps://[email protected]:465",
location: "",
mailCollection: "",
defaultFrom: "",
};
expect(isSendGrid(config)).toBe(true);

const invalidConfig: Config = {
smtpConnectionUri: "smtps://[email protected]:465",
location: "",
mailCollection: "",
defaultFrom: "",
};
expect(isSendGrid(invalidConfig)).toBe(false);
});
Loading
Loading