Skip to content

Commit f60b41b

Browse files
authored
Dont try to use expired refresh tokens (#7445)
1 parent 2f130b0 commit f60b41b

File tree

7 files changed

+17
-20
lines changed

7 files changed

+17
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Fix an issue where refresh_tokens would be used before checking whether they were expired. (#7442)

firebase-vscode/src/cli.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { Options } from "../../src/options";
1212
import { currentOptions, getCommandOptions } from "./options";
1313
import { EmulatorUiSelections } from "../common/messaging/types";
1414
import { pluginLogger } from "./logger-wrapper";
15-
import { setAccessToken } from "../../src/apiv2";
15+
import { getAccessToken, setAccessToken } from "../../src/apiv2";
1616
import {
1717
startAll as startAllEmulators,
1818
cleanShutdown as stopAllEmulators,
@@ -56,7 +56,7 @@ export async function requireAuthWrapper(
5656
return (
5757
account &&
5858
account.user.email === optionsUser.email &&
59-
account.tokens.access_token === optionsTokens.access_token // TODO: check if this is necessary
59+
account.tokens.refresh_token === optionsTokens.refresh_token // Should check refresh token which is consistent, not access_token which is short lived.
6060
);
6161
}
6262

@@ -80,8 +80,12 @@ export async function requireAuthWrapper(
8080
// over Google login tokens and must be removed if a Google
8181
// account is the current user.
8282
try {
83-
setAccessToken(); // clears the current access token
8483
const userEmail = await requireAuth(currentOptions.value); // client email
84+
// SetAccessToken is necessary here to ensure that access_tokens are available when:
85+
// - we are using tokens from configstore (aka those set by firebase login), AND
86+
// - we are calling CLI code that skips Command (where we normally call this)
87+
88+
setAccessToken(await getAccessToken());
8589
if (userEmail) {
8690
pluginLogger.debug("User found: ", userEmail);
8791

src/auth.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,13 @@ export function getAllAccounts(): Account[] {
106106

107107
/**
108108
* Set the globally active account. Modifies the options object
109-
* and sets global refresh and access token state.
109+
* and sets global refresh token state.
110110
* @param options options object.
111111
* @param account account to make active.
112112
*/
113-
export async function setActiveAccount(options: any, account: Account) {
113+
export function setActiveAccount(options: any, account: Account) {
114114
if (account.tokens.refresh_token) {
115115
setRefreshToken(account.tokens.refresh_token);
116-
setAccessToken(await apiv2.getAccessToken());
117116
}
118117

119118
options.user = account.user;
@@ -128,14 +127,6 @@ export function setRefreshToken(token: string) {
128127
apiv2.setRefreshToken(token);
129128
}
130129

131-
/**
132-
* Set the global access token in both api and apiv2.
133-
* @param token access token string
134-
*/
135-
export function setAccessToken(token: string) {
136-
apiv2.setAccessToken(token);
137-
}
138-
139130
/**
140131
* Select the right account to use based on the --account flag and the
141132
* project defaults.

src/command.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ export class Command {
319319
const activeAccount = selectAccount(account, projectRoot);
320320

321321
if (activeAccount) {
322-
await setActiveAccount(options, activeAccount);
322+
setActiveAccount(options, activeAccount);
323323
}
324324

325325
this.applyRC(options);

src/commands/login.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import * as _ from "lodash";
21
import * as clc from "colorette";
32

43
import { Command } from "../command";
@@ -57,7 +56,7 @@ export const command = new Command("login")
5756
// the authorization callback couldn't redirect to localhost.
5857
const useLocalhost = isCloudEnvironment() ? false : options.localhost;
5958

60-
const result = await auth.loginGoogle(useLocalhost, _.get(user, "email"));
59+
const result = await auth.loginGoogle(useLocalhost, user?.email);
6160
configstore.set("user", result.user);
6261
configstore.set("tokens", result.tokens);
6362
// store login scopes in case mandatory scopes grow over time

src/init/features/account.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export async function doSetup(setup: any, config: any, options: any): Promise<vo
7373
}
7474

7575
// Set the global auth state
76-
await setActiveAccount(options, account);
76+
setActiveAccount(options, account);
7777

7878
// Set the project default user
7979
if (config.projectDir) {

src/requireAuth.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ async function autoAuth(options: Options, authScopes: string[]): Promise<void |
5151
}
5252
if (process.env.MONOSPACE_ENV && token && clientEmail) {
5353
// Within monospace, this a OAuth token for the user, so we make it the active user.
54-
await setActiveAccount(options, {
54+
setActiveAccount(options, {
5555
user: { email: clientEmail },
5656
tokens: { access_token: token },
5757
});
@@ -110,6 +110,8 @@ export async function requireAuth(options: any): Promise<string | void> {
110110
throw new FirebaseError(AUTH_ERROR_MESSAGE);
111111
}
112112

113-
await setActiveAccount(options, { user, tokens });
113+
// TODO: 90 percent sure this is redundant, as the only time we hit this is if options.user/options.token is set, and
114+
// setActiveAccount is the only code that sets those.
115+
setActiveAccount(options, { user, tokens });
114116
return user.email;
115117
}

0 commit comments

Comments
 (0)