Skip to content

Commit 797d012

Browse files
authored
Merge pull request #2309 from firebase/next
Release: storage-resize-images 0.2.8, firestore-send-email 0.1.37
2 parents abfd8b1 + 654f4f6 commit 797d012

22 files changed

+1117
-84
lines changed

.github/workflows/readmes-updated.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
echo "::set-output name=dir::$(npm config get prefix)"
4545
4646
- name: Cache global dependencies
47-
uses: actions/cache@v2
47+
uses: actions/cache@v4
4848
with:
4949
path: ${{ steps.global-deps-setup.outputs.dir }}
5050
key:

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ You can also browse official Firebase extensions on the [Extensions Marketplace]
1616

1717
Documentation for the [Extensions by Firebase](https://firebase.google.com/docs/extensions) section are now stored in this repository.
1818

19-
They can be found under [Docs](https://github.com/firebase/extensions/docs)
19+
They can be found under [Docs](https://github.com/firebase/extensions/tree/master/docs)

firestore-send-email/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## Version 0.1.37
2+
3+
feat: add support for OAuth2 authentication
4+
5+
fix: default replyTo issue introduced in 0.1.35
6+
7+
fix: sendgrid attachment bug introduced in 0.1.35
8+
19
## Version 0.1.36
210

311
feat - move to Node.js 20 runtimes

firestore-send-email/PREINSTALL.md

Lines changed: 137 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,150 @@ Add this document to the Firestore mail collection to send categorized emails.
3939

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

42-
#### Setup Google App Passwords
42+
#### Setting Up OAuth2 Authentication
43+
44+
This section will help you set up OAuth2 authentication for the extension, using GCP (Gmail) as an example.
45+
46+
The extension is agnostic with respect to OAuth2 provider. You just need to provide it with valid Client ID, Client Secret, and Refresh Token parameters.
47+
48+
##### Step 1: Create OAuth Credentials in Google Cloud Platform
49+
50+
1. Go to the [Google Cloud Console](https://console.cloud.google.com/)
51+
2. Select your project
52+
3. In the left sidebar, navigate to **APIs & Services > Credentials**
53+
4. Click Create Credentials and select **OAuth client ID**
54+
5. Set the application type to **Web application**
55+
6. Give your OAuth client a name (e.g., "Firestore Send Email Extension")
56+
7. Under **Authorized redirect URIs**, add the URI where you'll receive the OAuth callback, for example, `http://localhost:8080/oauth/callback`.
57+
58+
**Note**: The redirect URI in your OAuth client settings MUST match exactly the callback URL in your code.
59+
60+
8. Click **Create**.
61+
62+
##### Step 2: Configure OAuth Consent Screen
63+
64+
1. In Google Cloud Console, go to **APIs & Services > OAuth consent screen**
65+
2. Choose the appropriate user type:
66+
- **External**: For applications used by any Google user
67+
- **Internal**: For applications used only by users in your organization
68+
69+
> **Important Note**: If your OAuth consent screen is in "Testing" status, refresh tokens will expire after 7 days unless the User Type is set to "Internal."
70+
71+
##### Step 3: Generate a Refresh Token
4372

44-
**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:
73+
You can use a standalone helper script (`oauth2-refresh-token-helper.js`) that generates a refresh token without requiring any npm installations.
74+
75+
**Prerequisites:**
76+
- You must have Node.js installed on your machine
4577

46-
1. Go to your [Google Account](https://myaccount.google.com/).
47-
2. Select **Security**.
48-
3. Under "Signing in to Google," select **App Passwords**. You may need to sign in. If you don’t have this option, it might be because:
49-
1. 2-Step Verification is not set up for your account.
50-
2. 2-Step Verification is only set up for security keys.
51-
3. Your account is through work, school, or other organization.
52-
4. You turned on Advanced Protection.
53-
4. At the bottom, choose **Select app** and choose **Other** option and then write the name of the app password (e.g. `Firebase Trigger Email from Firestore Extension`) and click **Generate**.
54-
5. Follow the instructions to enter the App Password. The App Password is the 16-character code in the yellow bar on your device.
55-
6. Tap **Done**.
78+
**Download the script:**
79+
1. Download the script using curl, wget, or directly from your browser:
80+
```bash
81+
# Using curl
82+
curl -o oauth2-refresh-token-helper.js https://raw.githubusercontent.com/firebase/extensions/refs/heads/master/firestore-send-email/scripts/oauth2-refresh-token-helper.js
83+
84+
# Using wget
85+
wget https://raw.githubusercontent.com/firebase/extensions/refs/heads/master/firestore-send-email/scripts/oauth2-refresh-token-helper.js
86+
```
5687

57-
Now you can use your Google username with the generated password to authorize the extension.
88+
You can also [view the script on GitHub](https://github.com/firebase/extensions/blob/master/firestore-send-email/scripts/oauth2-refresh-token-helper.js) and download it manually.
5889

59-
#### Setup Hotmail Passwords
90+
> **Note**: If you are creating your own application to obtain a refresh token, in a Node.js environment where you can use npm packages, consider using the official google-auth-library instead:
91+
>
92+
> 1. Install the library: `npm install google-auth-library`
93+
> 2. Then use it like this:
94+
> ```javascript
95+
> import { OAuth2Client } from "google-auth-library";
96+
>
97+
> // Initialize OAuth client
98+
> const oAuth2Client = new OAuth2Client(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI);
99+
>
100+
> // Generate authorization URL
101+
> const authorizeUrl = oAuth2Client.generateAuthUrl({
102+
> access_type: "offline",
103+
> prompt: "consent",
104+
> scope: ["https://mail.google.com/"], // Full Gmail access
105+
> });
106+
>
107+
> // After receiving the code from the callback:
108+
> const { tokens } = await oAuth2Client.getToken(code);
109+
> const refreshToken = tokens.refresh_token;
110+
> ```
60111
61-
To use your Outlook/Hotmail email account with this extension, you'll need to have 2FA enabled on your account, and [Create an App Password](https://support.microsoft.com/en-us/help/12409/microsoft-account-app-passwords-and-two-step-verification).
112+
2. Run the script with Node.js:
62113
63-
#### Additional setup
114+
```bash
115+
node oauth2-refresh-token-helper.js
116+
```
64117
65-
Before installing this extension, make sure that you've [set up a Cloud Firestore database](https://firebase.google.com/docs/firestore/quickstart) in your Firebase project.
118+
3. The script supports the following command-line options:
119+
```
120+
--port, -p Port to run the server on (default: 8080 or PORT env var)
121+
--id, -i Google OAuth Client ID
122+
--secret, -s Google OAuth Client Secret
123+
--output, -o Output file to save the refresh token (default: refresh_token.txt)
124+
--help, -h Show help information
125+
```
126+
127+
4. You can either provide your credentials as command-line arguments or set them as environment variables:
128+
```bash
129+
# Using environment variables
130+
export CLIENT_ID=your_client_id
131+
export CLIENT_SECRET=your_client_secret
132+
node oauth2-refresh-token-helper.js
133+
134+
# Using command-line arguments
135+
node oauth2-refresh-token-helper.js --id=your_client_id --secret=your_client_secret
136+
```
137+
138+
5. The script will:
139+
- Start a local web server
140+
- Open your browser to the OAuth consent page
141+
- Receive the authorization code
142+
- Exchange the code for tokens
143+
- Save the refresh token to a file (default: `refresh_token.txt`)
144+
- Display the refresh token in your browser
145+
146+
6. **Important**: The redirect URI in the script (`http://localhost:8080/oauth/callback` by default) **MUST** match exactly what you configured in the Google Cloud Console OAuth client settings.
147+
148+
7. The script automatically requests the appropriate scope for Gmail access (`https://mail.google.com/`) and sets the authorization parameters to always receive a refresh token (`access_type: "offline"` and `prompt: "consent"`).
149+
150+
##### Step 4: Configure the Firestore Send Email Extension
151+
152+
When installing the extension, select "OAuth2" as the **Authentication Type** and provide the following parameters:
153+
154+
- **OAuth2 SMTP Host**: `smtp.gmail.com` (for Gmail)
155+
- **OAuth2 SMTP Port**: `465` (for SMTPS) or `587` (for STARTTLS)
156+
- **Use Secure OAuth2 Connection**: `true` (for port 465) or `false` (for port 587)
157+
- **OAuth2 Client ID**: Your Client ID from GCP
158+
- **OAuth2 Client Secret**: Your Client Secret from GCP
159+
- **OAuth2 Refresh Token**: The refresh token generated in Step 3
160+
- **SMTP User**: Your full Gmail email address
161+
162+
Leave `Use secure OAuth2 connection?` as the default value `true`.
163+
164+
##### Troubleshooting
165+
166+
###### Refresh Token Expiration
167+
168+
- **Testing Status**: If your OAuth consent screen is in "Testing" status, refresh tokens expire after 7 days unless User Type is set to "Internal"
169+
- **Solution**: Either publish your app or ensure User Type is set to "Internal" in the OAuth consent screen settings
170+
171+
###### No Refresh Token Received
172+
173+
- **Problem**: If you don't receive a refresh token during the OAuth flow
174+
- **Solution**: Make sure you've revoked previous access or forced consent by going to [Google Account Security](https://myaccount.google.com/security) > Third-party apps with account access
175+
176+
###### Scope Issues
177+
178+
- **Problem**: If you see authentication errors, you might not have the correct scopes
179+
- **Solution**: Ensure you've added `https://mail.google.com/` as a scope in the OAuth consent screen
180+
181+
###### Additional Resources
182+
183+
- [Google OAuth2 Documentation](https://developers.google.com/identity/protocols/oauth2)
184+
- [Nodemailer OAuth2 Guide](https://nodemailer.com/smtp/oauth2/)
185+
- [Firebase Extensions Documentation](https://firebase.google.com/docs/extensions)
66186

67187
#### Automatic Deletion of Email Documents
68188

firestore-send-email/README.md

Lines changed: 153 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,30 +47,150 @@ Add this document to the Firestore mail collection to send categorized emails.
4747

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

50-
#### Setup Google App Passwords
50+
#### Setting Up OAuth2 Authentication
51+
52+
This section will help you set up OAuth2 authentication for the extension, using GCP (Gmail) as an example.
53+
54+
The extension is agnostic with respect to OAuth2 provider. You just need to provide it with valid Client ID, Client Secret, and Refresh Token parameters.
55+
56+
##### Step 1: Create OAuth Credentials in Google Cloud Platform
57+
58+
1. Go to the [Google Cloud Console](https://console.cloud.google.com/)
59+
2. Select your project
60+
3. In the left sidebar, navigate to **APIs & Services > Credentials**
61+
4. Click Create Credentials and select **OAuth client ID**
62+
5. Set the application type to **Web application**
63+
6. Give your OAuth client a name (e.g., "Firestore Send Email Extension")
64+
7. Under **Authorized redirect URIs**, add the URI where you'll receive the OAuth callback, for example, `http://localhost:8080/oauth/callback`.
65+
66+
**Note**: The redirect URI in your OAuth client settings MUST match exactly the callback URL in your code.
67+
68+
8. Click **Create**.
69+
70+
##### Step 2: Configure OAuth Consent Screen
71+
72+
1. In Google Cloud Console, go to **APIs & Services > OAuth consent screen**
73+
2. Choose the appropriate user type:
74+
- **External**: For applications used by any Google user
75+
- **Internal**: For applications used only by users in your organization
76+
77+
> **Important Note**: If your OAuth consent screen is in "Testing" status, refresh tokens will expire after 7 days unless the User Type is set to "Internal."
78+
79+
##### Step 3: Generate a Refresh Token
5180

52-
**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:
81+
You can use a standalone helper script (`oauth2-refresh-token-helper.js`) that generates a refresh token without requiring any npm installations.
82+
83+
**Prerequisites:**
84+
- You must have Node.js installed on your machine
5385

54-
1. Go to your [Google Account](https://myaccount.google.com/).
55-
2. Select **Security**.
56-
3. Under "Signing in to Google," select **App Passwords**. You may need to sign in. If you don’t have this option, it might be because:
57-
1. 2-Step Verification is not set up for your account.
58-
2. 2-Step Verification is only set up for security keys.
59-
3. Your account is through work, school, or other organization.
60-
4. You turned on Advanced Protection.
61-
4. At the bottom, choose **Select app** and choose **Other** option and then write the name of the app password (e.g. `Firebase Trigger Email from Firestore Extension`) and click **Generate**.
62-
5. Follow the instructions to enter the App Password. The App Password is the 16-character code in the yellow bar on your device.
63-
6. Tap **Done**.
86+
**Download the script:**
87+
1. Download the script using curl, wget, or directly from your browser:
88+
```bash
89+
# Using curl
90+
curl -o oauth2-refresh-token-helper.js https://raw.githubusercontent.com/firebase/extensions/refs/heads/master/firestore-send-email/scripts/oauth2-refresh-token-helper.js
91+
92+
# Using wget
93+
wget https://raw.githubusercontent.com/firebase/extensions/refs/heads/master/firestore-send-email/scripts/oauth2-refresh-token-helper.js
94+
```
6495

65-
Now you can use your Google username with the generated password to authorize the extension.
96+
You can also [view the script on GitHub](https://github.com/firebase/extensions/blob/master/firestore-send-email/scripts/oauth2-refresh-token-helper.js) and download it manually.
6697

67-
#### Setup Hotmail Passwords
98+
> **Note**: If you are creating your own application to obtain a refresh token, in a Node.js environment where you can use npm packages, consider using the official google-auth-library instead:
99+
>
100+
> 1. Install the library: `npm install google-auth-library`
101+
> 2. Then use it like this:
102+
> ```javascript
103+
> import { OAuth2Client } from "google-auth-library";
104+
>
105+
> // Initialize OAuth client
106+
> const oAuth2Client = new OAuth2Client(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI);
107+
>
108+
> // Generate authorization URL
109+
> const authorizeUrl = oAuth2Client.generateAuthUrl({
110+
> access_type: "offline",
111+
> prompt: "consent",
112+
> scope: ["https://mail.google.com/"], // Full Gmail access
113+
> });
114+
>
115+
> // After receiving the code from the callback:
116+
> const { tokens } = await oAuth2Client.getToken(code);
117+
> const refreshToken = tokens.refresh_token;
118+
> ```
68119
69-
To use your Outlook/Hotmail email account with this extension, you'll need to have 2FA enabled on your account, and [Create an App Password](https://support.microsoft.com/en-us/help/12409/microsoft-account-app-passwords-and-two-step-verification).
120+
2. Run the script with Node.js:
70121
71-
#### Additional setup
122+
```bash
123+
node oauth2-refresh-token-helper.js
124+
```
72125
73-
Before installing this extension, make sure that you've [set up a Cloud Firestore database](https://firebase.google.com/docs/firestore/quickstart) in your Firebase project.
126+
3. The script supports the following command-line options:
127+
```
128+
--port, -p Port to run the server on (default: 8080 or PORT env var)
129+
--id, -i Google OAuth Client ID
130+
--secret, -s Google OAuth Client Secret
131+
--output, -o Output file to save the refresh token (default: refresh_token.txt)
132+
--help, -h Show help information
133+
```
134+
135+
4. You can either provide your credentials as command-line arguments or set them as environment variables:
136+
```bash
137+
# Using environment variables
138+
export CLIENT_ID=your_client_id
139+
export CLIENT_SECRET=your_client_secret
140+
node oauth2-refresh-token-helper.js
141+
142+
# Using command-line arguments
143+
node oauth2-refresh-token-helper.js --id=your_client_id --secret=your_client_secret
144+
```
145+
146+
5. The script will:
147+
- Start a local web server
148+
- Open your browser to the OAuth consent page
149+
- Receive the authorization code
150+
- Exchange the code for tokens
151+
- Save the refresh token to a file (default: `refresh_token.txt`)
152+
- Display the refresh token in your browser
153+
154+
6. **Important**: The redirect URI in the script (`http://localhost:8080/oauth/callback` by default) **MUST** match exactly what you configured in the Google Cloud Console OAuth client settings.
155+
156+
7. The script automatically requests the appropriate scope for Gmail access (`https://mail.google.com/`) and sets the authorization parameters to always receive a refresh token (`access_type: "offline"` and `prompt: "consent"`).
157+
158+
##### Step 4: Configure the Firestore Send Email Extension
159+
160+
When installing the extension, select "OAuth2" as the **Authentication Type** and provide the following parameters:
161+
162+
- **OAuth2 SMTP Host**: `smtp.gmail.com` (for Gmail)
163+
- **OAuth2 SMTP Port**: `465` (for SMTPS) or `587` (for STARTTLS)
164+
- **Use Secure OAuth2 Connection**: `true` (for port 465) or `false` (for port 587)
165+
- **OAuth2 Client ID**: Your Client ID from GCP
166+
- **OAuth2 Client Secret**: Your Client Secret from GCP
167+
- **OAuth2 Refresh Token**: The refresh token generated in Step 3
168+
- **SMTP User**: Your full Gmail email address
169+
170+
Leave `Use secure OAuth2 connection?` as the default value `true`.
171+
172+
##### Troubleshooting
173+
174+
###### Refresh Token Expiration
175+
176+
- **Testing Status**: If your OAuth consent screen is in "Testing" status, refresh tokens expire after 7 days unless User Type is set to "Internal"
177+
- **Solution**: Either publish your app or ensure User Type is set to "Internal" in the OAuth consent screen settings
178+
179+
###### No Refresh Token Received
180+
181+
- **Problem**: If you don't receive a refresh token during the OAuth flow
182+
- **Solution**: Make sure you've revoked previous access or forced consent by going to [Google Account Security](https://myaccount.google.com/security) > Third-party apps with account access
183+
184+
###### Scope Issues
185+
186+
- **Problem**: If you see authentication errors, you might not have the correct scopes
187+
- **Solution**: Ensure you've added `https://mail.google.com/` as a scope in the OAuth consent screen
188+
189+
###### Additional Resources
190+
191+
- [Google OAuth2 Documentation](https://developers.google.com/identity/protocols/oauth2)
192+
- [Nodemailer OAuth2 Guide](https://nodemailer.com/smtp/oauth2/)
193+
- [Firebase Extensions Documentation](https://firebase.google.com/docs/extensions)
74194

75195
#### Automatic Deletion of Email Documents
76196

@@ -99,6 +219,8 @@ You can find more information about this extension in the following articles:
99219

100220
**Configuration Parameters:**
101221

222+
* Authentication Type: The authentication type to be used for the SMTP server (e.g., OAuth2, Username & Password.
223+
102224
* SMTP connection URI: A URI representing an SMTP server this extension can use to deliver email. Note that port 25 is blocked by Google Cloud Platform, so we recommend using port 587 for SMTP connections. If you're using the SMTPS protocol, we recommend using port 465. In order to keep passwords secure, it is recommended to omit the password from the connection string while using the `SMTP Password` field for entering secrets and passwords. Passwords and secrets should now be included in `SMTP password` field.
103225
Secure format:
104226
`smtps://[email protected]@smtp.gmail.com:465` (username only)
@@ -109,6 +231,20 @@ password)
109231

110232
* SMTP password: User password for the SMTP server
111233

234+
* OAuth2 SMTP Host: The OAuth2 hostname of the SMTP server (e.g., smtp.gmail.com).
235+
236+
* OAuth2 SMTP Port: The OAuth2 port number for the SMTP server (e.g., 465 for SMTPS, 587 for STARTTLS).
237+
238+
* Use secure OAuth2 connection?: Set to true to enable a secure connection (TLS/SSL) when using OAuth2 authentication for the SMTP server.
239+
240+
* OAuth2 Client ID: The OAuth2 Client ID for authentication with the SMTP server.
241+
242+
* OAuth2 Client Secret: The OAuth2 Client Secret for authentication with the SMTP server.
243+
244+
* OAuth2 Refresh Token: The OAuth2 Refresh Token for authentication with the SMTP server.
245+
246+
* OAuth2 SMTP User: The OAuth2 user email or username for SMTP authentication.
247+
112248
* Email documents collection: What is the path to the collection that contains the documents used to build and send the emails?
113249

114250
* Default FROM address: The email address to use as the sender's address (if it's not specified in the added email document). You can optionally include a name with the email address (`Friendly Firebaser <[email protected]>`). This parameter does not work with [Gmail SMTP](https://nodemailer.com/usage/using-gmail/).

0 commit comments

Comments
 (0)