Skip to content

Commit

Permalink
Merge master into release
Browse files Browse the repository at this point in the history
  • Loading branch information
google-oss-bot committed Jan 31, 2023
2 parents 90725ba + 0bab0b7 commit 1de6be4
Show file tree
Hide file tree
Showing 59 changed files with 833 additions and 182 deletions.
5 changes: 5 additions & 0 deletions .changeset/chilled-boats-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@firebase/auth': patch
---

Expose TOKEN_EXPIRED error when mfa unenroll logs out the user.
6 changes: 6 additions & 0 deletions .changeset/fresh-experts-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@firebase/database-compat": patch
"@firebase/database": patch
---

Fixed issue where hostname set by `connectDatabaseEmulator` was being overridden by longpolling response
8 changes: 8 additions & 0 deletions .changeset/hungry-glasses-impress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"firebase": minor
"@firebase/storage": minor
"@firebase/storage-types": minor
"@firebase/storage-compat": minor
---

Fixed issue where users were unable to check if an Error was an instance of `StorageError`.
19 changes: 19 additions & 0 deletions .changeset/ninety-taxis-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
'@firebase/auth': patch
'@firebase/auth-compat': patch
'@firebase/database': patch
'@firebase/database-compat': patch
'firebase': patch
'@firebase/firestore': patch
'@firebase/firestore-compat': patch
'@firebase/functions': patch
'@firebase/functions-compat': patch
'@firebase/messaging': patch
'@firebase/messaging-compat': patch
'@firebase/rules-unit-testing': patch
'@firebase/storage': patch
'@firebase/template': patch
'@firebase/util': patch
---

Added browser CJS entry points (expected by Jest when using JSDOM mode).
5 changes: 5 additions & 0 deletions .changeset/slimy-elephants-hear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@firebase/firestore": patch
---

Reduce memory usage by applying query check sooner in remote document cache.
79 changes: 70 additions & 9 deletions common/api-review/storage.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,11 @@ export function getStorage(app?: FirebaseApp, bucketUrl?: string): FirebaseStora
// @public
export function getStream(ref: StorageReference, maxDownloadSizeBytes?: number): NodeJS.ReadableStream;

// Warning: (ae-forgotten-export) The symbol "StorageError" needs to be exported by the entry point index.d.ts
//
// @internal (undocumented)
export function _invalidArgument(message: string): StorageError_2;
export function _invalidArgument(message: string): StorageError;

// @internal (undocumented)
export function _invalidRootOperation(name: string): StorageError_2;
export function _invalidRootOperation(name: string): StorageError;

// @public
export function list(ref: StorageReference, options?: ListOptions): Promise<ListResult>;
Expand Down Expand Up @@ -217,8 +215,71 @@ export interface SettableMetadata {
}

// @public
export interface StorageError extends FirebaseError {
serverResponse: string | null;
export class StorageError extends FirebaseError {
constructor(code: StorageErrorCode, message: string, status_?: number);
_codeEquals(code: StorageErrorCode): boolean;
customData: {
serverResponse: string | null;
};
get serverResponse(): null | string;
set serverResponse(serverResponse: string | null);
// (undocumented)
get status(): number;
set status(status: number);
}

// @public
export enum StorageErrorCode {
// (undocumented)
APP_DELETED = "app-deleted",
// (undocumented)
BUCKET_NOT_FOUND = "bucket-not-found",
// (undocumented)
CANCELED = "canceled",
// (undocumented)
CANNOT_SLICE_BLOB = "cannot-slice-blob",
// (undocumented)
INTERNAL_ERROR = "internal-error",
// (undocumented)
INVALID_ARGUMENT = "invalid-argument",
// (undocumented)
INVALID_ARGUMENT_COUNT = "invalid-argument-count",
// (undocumented)
INVALID_CHECKSUM = "invalid-checksum",
// (undocumented)
INVALID_DEFAULT_BUCKET = "invalid-default-bucket",
// (undocumented)
INVALID_EVENT_NAME = "invalid-event-name",
// (undocumented)
INVALID_FORMAT = "invalid-format",
// (undocumented)
INVALID_ROOT_OPERATION = "invalid-root-operation",
// (undocumented)
INVALID_URL = "invalid-url",
// (undocumented)
NO_DEFAULT_BUCKET = "no-default-bucket",
// (undocumented)
NO_DOWNLOAD_URL = "no-download-url",
// (undocumented)
OBJECT_NOT_FOUND = "object-not-found",
// (undocumented)
PROJECT_NOT_FOUND = "project-not-found",
// (undocumented)
QUOTA_EXCEEDED = "quota-exceeded",
// (undocumented)
RETRY_LIMIT_EXCEEDED = "retry-limit-exceeded",
// (undocumented)
SERVER_FILE_WRONG_SIZE = "server-file-wrong-size",
// (undocumented)
UNAUTHENTICATED = "unauthenticated",
// (undocumented)
UNAUTHORIZED = "unauthorized",
// (undocumented)
UNAUTHORIZED_APP = "unauthorized-app",
// (undocumented)
UNKNOWN = "unknown",
// (undocumented)
UNSUPPORTED_ENVIRONMENT = "unsupported-environment"
}

// @public
Expand Down Expand Up @@ -318,20 +379,20 @@ export class _UploadTask {
constructor(ref: _Reference, blob: _FbsBlob, metadata?: Metadata | null);
_blob: _FbsBlob;
cancel(): boolean;
catch<T>(onRejected: (p1: StorageError_2) => T | Promise<T>): Promise<T>;
catch<T>(onRejected: (p1: StorageError) => T | Promise<T>): Promise<T>;
// (undocumented)
isExponentialBackoffExpired(): boolean;
// Warning: (ae-forgotten-export) The symbol "Metadata" needs to be exported by the entry point index.d.ts
_metadata: Metadata | null;
// Warning: (ae-forgotten-export) The symbol "Unsubscribe" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Subscribe" needs to be exported by the entry point index.d.ts
on(type: _TaskEvent, nextOrObserver?: StorageObserver<UploadTaskSnapshot> | null | ((snapshot: UploadTaskSnapshot) => unknown), error?: ((a: StorageError_2) => unknown) | null, completed?: CompleteFn | null): Unsubscribe_2 | Subscribe_2<UploadTaskSnapshot>;
on(type: _TaskEvent, nextOrObserver?: StorageObserver<UploadTaskSnapshot> | null | ((snapshot: UploadTaskSnapshot) => unknown), error?: ((a: StorageError) => unknown) | null, completed?: CompleteFn | null): Unsubscribe_2 | Subscribe_2<UploadTaskSnapshot>;
pause(): boolean;
resume(): boolean;
get snapshot(): UploadTaskSnapshot;
// Warning: (ae-forgotten-export) The symbol "InternalTaskState" needs to be exported by the entry point index.d.ts
_state: InternalTaskState;
then<U>(onFulfilled?: ((value: UploadTaskSnapshot) => U | Promise<U>) | null, onRejected?: ((error: StorageError_2) => U | Promise<U>) | null): Promise<U>;
then<U>(onFulfilled?: ((value: UploadTaskSnapshot) => U | Promise<U>) | null, onRejected?: ((error: StorageError) => U | Promise<U>) | null): Promise<U>;
_transferred: number;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/analytics-types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ export interface Promotion {

/**
* Dynamic configuration fetched from server.
* See https://firebase.google.com/docs/projects/api/reference/rest/v1beta1/projects.webApps/getConfig
* See https://firebase.google.com/docs/reference/firebase-management/rest/v1beta1/projects.webApps/getConfig
*/
interface DynamicConfig {
projectId: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/analytics/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export interface ThrottleMetadata {

/**
* Dynamic configuration fetched from server.
* See https://firebase.google.com/docs/projects/api/reference/rest/v1beta1/projects.webApps/getConfig
* See https://firebase.google.com/docs/reference/firebase-management/rest/v1beta1/projects.webApps/getConfig
*/
export interface DynamicConfig {
projectId: string;
Expand Down
6 changes: 5 additions & 1 deletion packages/auth-compat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
"require": "./dist/index.node.cjs.js"
},
"esm5": "./dist/index.esm.js",
"default": "./dist/index.esm2017.js"
"default": "./dist/index.esm2017.js",
"browser": {
"require": "./dist/index.cjs.js",
"import": "./dist/index.esm2017.js"
}
},
"./package.json": "./package.json"
},
Expand Down
13 changes: 13 additions & 0 deletions packages/auth-compat/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ const browserBuilds = [
treeshake: {
moduleSideEffects: false
}
},
{
input: 'index.ts',
output: {
file: 'dist/index.cjs.js',
format: 'cjs',
sourcemap: true
},
plugins: es2017BuildPlugins,
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)),
treeshake: {
moduleSideEffects: false
}
}
];

Expand Down
4 changes: 4 additions & 0 deletions packages/auth/demo/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@
id="sign-in-with-email-and-password">
Sign In with Email and Password
</button>
<button class="btn btn-block btn-primary"
id="reauth-with-email-and-password">
Reauthenticate with Email and Password
</button>
</form>
<form class="form form-bordered no-submit">
<input type="text" id="user-custom-token" class="form-control"
Expand Down
44 changes: 42 additions & 2 deletions packages/auth/demo/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,10 @@ function showMultiFactorStatus(activeUser) {
const label = info && (info.displayName || info.uid);
if (label) {
$('#enrolled-factors-drop-down').removeClass('open');
// Set the last user, in case the current user is logged out.
// This can happen if the MFA option being unenrolled is the one that was most recently enrolled into.
// See - https://github.com/firebase/firebase-js-sdk/issues/3233
setLastUser(activeUser);
mfaUser.unenroll(info).then(() => {
refreshUserData();
alertSuccess('Multi-factor successfully unenrolled.');
Expand Down Expand Up @@ -278,6 +282,9 @@ function onAuthError(error) {
handleMultiFactorSignIn(getMultiFactorResolver(auth, error));
} else {
alertError('Error: ' + error.code);
if (error.code === 'auth/user-token-expired') {
alertError('Token expired, please reauthenticate.');
}
}
}

Expand Down Expand Up @@ -403,13 +410,41 @@ function onLinkWithEmailLink() {
* Re-authenticate a user with email link credential.
*/
function onReauthenticateWithEmailLink() {
if (!activeUser()) {
alertError(
'No user logged in. Select the "Last User" tab to reauth the previous user.'
);
return;
}
const email = $('#link-with-email-link-email').val();
const link = $('#link-with-email-link-link').val() || undefined;
const credential = EmailAuthProvider.credentialWithLink(email, link);
// This will not set auth.currentUser to lastUser if the lastUser is reauthenticated.
reauthenticateWithCredential(activeUser(), credential).then(result => {
logAdditionalUserInfo(result);
refreshUserData();
alertSuccess('User reauthenticated!');
alertSuccess('User reauthenticated with email link!');
}, onAuthError);
}

/**
* Re-authenticate a user with email and password.
*/
function onReauthenticateWithEmailAndPassword() {
if (!activeUser()) {
alertError(
'No user logged in. Select the "Last User" tab to reauth the previous user.'
);
return;
}
const email = $('#signin-email').val();
const password = $('#signin-password').val();
const credential = EmailAuthProvider.credential(email, password);
// This will not set auth.currentUser to lastUser if the lastUser is reauthenticated.
reauthenticateWithCredential(activeUser(), credential).then(result => {
logAdditionalUserInfo(result);
refreshUserData();
alertSuccess('User reauthenticated with email/password!');
}, onAuthError);
}

Expand Down Expand Up @@ -1264,7 +1299,9 @@ function signInWithPopupRedirect(provider) {
break;
case 'reauthenticate':
if (!activeUser()) {
alertError('No user logged in.');
alertError(
'No user logged in. Select the "Last User" tab to reauth the previous user.'
);
return;
}
inst = activeUser();
Expand Down Expand Up @@ -1860,6 +1897,9 @@ function initApp() {
// Actions listeners.
$('#sign-up-with-email-and-password').click(onSignUp);
$('#sign-in-with-email-and-password').click(onSignInWithEmailAndPassword);
$('#reauth-with-email-and-password').click(
onReauthenticateWithEmailAndPassword
);
$('.sign-in-with-custom-token').click(onSignInWithCustomToken);
$('#sign-in-anonymously').click(onSignInAnonymously);
$('#sign-in-with-generic-idp-credential').click(
Expand Down
12 changes: 10 additions & 2 deletions packages/auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@
"default": "./dist/index.webworker.esm5.js"
},
"esm5": "./dist/esm5/index.js",
"default": "./dist/esm2017/index.js"
"default": "./dist/esm2017/index.js",
"browser": {
"require": "./dist/browser-cjs/index.js",
"import": "./dist/esm2017/index.js"
}
},
"./cordova": {
"types": "./dist/cordova/index.cordova.d.ts",
Expand All @@ -57,7 +61,11 @@
"default": "./dist/cordova/internal.js"
},
"esm5": "./dist/esm5/internal.js",
"default": "./dist/esm2017/internal.js"
"default": "./dist/esm2017/internal.js",
"browser": {
"require": "./dist/browser-cjs/internal.js",
"import": "./dist/esm2017/internal.js"
}
},
"./package.json": "./package.json"
},
Expand Down
12 changes: 12 additions & 0 deletions packages/auth/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,18 @@ const browserBuilds = [
replace(generateBuildTargetReplaceConfig('esm', 2017))
],
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`))
},
{
input: {
index: 'index.ts',
internal: 'internal/index.ts'
},
output: [{ dir: 'dist/browser-cjs', format: 'cjs', sourcemap: true }],
plugins: [
...es2017BuildPlugins,
replace(generateBuildTargetReplaceConfig('cjs', 2017))
],
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`))
}
];

Expand Down
3 changes: 2 additions & 1 deletion packages/auth/src/core/strategies/credential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ export async function linkWithCredential(
*
* @remarks
* Use before operations such as {@link updatePassword} that require tokens from recent sign-in
* attempts. This method can be used to recover from a `CREDENTIAL_TOO_OLD_LOGIN_AGAIN` error.
* attempts. This method can be used to recover from a `CREDENTIAL_TOO_OLD_LOGIN_AGAIN` error
* or a `TOKEN_EXPIRED` error.
*
* @param user - The user.
* @param credential - The auth credential.
Expand Down
6 changes: 4 additions & 2 deletions packages/auth/src/mfa/mfa_user.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,10 @@ describe('core/mfa/mfa_user/MultiFactorUser', () => {
);
});

it('should swallow the error', async () => {
await mfaUser.unenroll(mfaInfo);
it('should throw TOKEN_EXPIRED error', async () => {
await expect(mfaUser.unenroll(mfaInfo)).to.be.rejectedWith(
'auth/user-token-expired'
);
});
});
});
Expand Down
Loading

0 comments on commit 1de6be4

Please sign in to comment.