fix: Auth persistence to localStorage (#3078)
* fix: user, team, and policies should be persisted to localStorage for faster boot * capture instead of ignore errors
This commit is contained in:
@@ -22,7 +22,7 @@ export default class BaseModel {
|
|||||||
try {
|
try {
|
||||||
// ensure that the id is passed if the document has one
|
// ensure that the id is passed if the document has one
|
||||||
if (!params) {
|
if (!params) {
|
||||||
params = this.toJS();
|
params = this.toAPI();
|
||||||
}
|
}
|
||||||
|
|
||||||
const model = await this.store.save({ ...params, id: this.id });
|
const model = await this.store.save({ ...params, id: this.id });
|
||||||
@@ -30,7 +30,7 @@ export default class BaseModel {
|
|||||||
// if saving is successful set the new values on the model itself
|
// if saving is successful set the new values on the model itself
|
||||||
set(this, { ...params, ...model });
|
set(this, { ...params, ...model });
|
||||||
|
|
||||||
this.persistedAttributes = this.toJS();
|
this.persistedAttributes = this.toAPI();
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -40,7 +40,7 @@ export default class BaseModel {
|
|||||||
|
|
||||||
updateFromJson = (data: any) => {
|
updateFromJson = (data: any) => {
|
||||||
set(this, data);
|
set(this, data);
|
||||||
this.persistedAttributes = this.toJS();
|
this.persistedAttributes = this.toAPI();
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch = (options?: any) => {
|
fetch = (options?: any) => {
|
||||||
@@ -64,15 +64,38 @@ export default class BaseModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a plain object representation of the model
|
* Returns a plain object representation of fields on the model for
|
||||||
|
* persistence to the server API
|
||||||
*
|
*
|
||||||
* @returns {Record<string, any>}
|
* @returns {Record<string, any>}
|
||||||
*/
|
*/
|
||||||
toJS = (): Record<string, any> => {
|
toAPI = (): Record<string, any> => {
|
||||||
const fields = getFieldsForModel(this);
|
const fields = getFieldsForModel(this);
|
||||||
return pick(this, fields) || [];
|
return pick(this, fields) || [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a plain object representation of all the properties on the model
|
||||||
|
* overrides the inbuilt toJSON method to avoid attempting to serialize store
|
||||||
|
*
|
||||||
|
* @returns {Record<string, any>}
|
||||||
|
*/
|
||||||
|
toJSON() {
|
||||||
|
const output: Partial<typeof this> = {};
|
||||||
|
|
||||||
|
for (const property in this) {
|
||||||
|
if (
|
||||||
|
// eslint-disable-next-line no-prototype-builtins
|
||||||
|
this.hasOwnProperty(property) &&
|
||||||
|
!["persistedAttributes", "store", "isSaving"].includes(property)
|
||||||
|
) {
|
||||||
|
output[property] = this[property];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a boolean indicating if the model has changed since it was last
|
* Returns a boolean indicating if the model has changed since it was last
|
||||||
* persisted to the server
|
* persisted to the server
|
||||||
@@ -80,7 +103,7 @@ export default class BaseModel {
|
|||||||
* @returns boolean true if unsaved
|
* @returns boolean true if unsaved
|
||||||
*/
|
*/
|
||||||
isDirty(): boolean {
|
isDirty(): boolean {
|
||||||
const attributes = this.toJS();
|
const attributes = this.toAPI();
|
||||||
|
|
||||||
if (Object.keys(attributes).length === 0) {
|
if (Object.keys(attributes).length === 0) {
|
||||||
console.warn("Checking dirty on model with no @Field decorators");
|
console.warn("Checking dirty on model with no @Field decorators");
|
||||||
|
|||||||
@@ -68,19 +68,21 @@ export default class AuthStore {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
data = JSON.parse(localStorage.getItem(AUTH_STORE) || "{}");
|
data = JSON.parse(localStorage.getItem(AUTH_STORE) || "{}");
|
||||||
} catch (_) {
|
} catch (err) {
|
||||||
// no-op Safari private mode
|
Sentry.captureException(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rehydrate(data);
|
this.rehydrate(data);
|
||||||
|
|
||||||
// persists this entire store to localstorage whenever any keys are changed
|
// persists this entire store to localstorage whenever any keys are changed
|
||||||
autorun(() => {
|
autorun(() => {
|
||||||
try {
|
try {
|
||||||
localStorage.setItem(AUTH_STORE, this.asJson);
|
localStorage.setItem(AUTH_STORE, this.asJson);
|
||||||
} catch (_) {
|
} catch (err) {
|
||||||
// no-op Safari private mode
|
Sentry.captureException(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// listen to the localstorage value changing in other tabs to react to
|
// listen to the localstorage value changing in other tabs to react to
|
||||||
// signin/signout events in other tabs and follow suite.
|
// signin/signout events in other tabs and follow suite.
|
||||||
window.addEventListener("storage", (event) => {
|
window.addEventListener("storage", (event) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user