force expire login cred

This commit is contained in:
fyears 2022-01-01 18:37:48 +08:00
parent 34d1b01c7b
commit 6832c9f649
5 changed files with 129 additions and 15 deletions

View File

@ -25,6 +25,7 @@
"@types/chai": "^4.2.22",
"@types/chai-as-promised": "^7.1.4",
"@types/jsdom": "^16.2.13",
"@types/lodash": "^4.14.178",
"@types/mime-types": "^2.1.1",
"@types/mocha": "^9.0.0",
"@types/node": "^14.14.37",
@ -60,6 +61,7 @@
"crypto-browserify": "^3.12.0",
"dropbox": "^10.22.0",
"localforage": "^1.10.0",
"lodash": "^4.17.21",
"mime-types": "^2.1.33",
"obsidian": "^0.12.0",
"path-browserify": "^1.0.1",

View File

@ -21,6 +21,7 @@ export interface DropboxConfig {
accessTokenExpiresAtTime: number;
accountID: string;
username: string;
credentialsShouldBeDeletedAtTime?: number;
}
export type WebdavAuthType = "digest" | "basic";
@ -41,6 +42,7 @@ export interface OnedriveConfig {
accessTokenExpiresAtTime: number;
deltaLink: string;
username: string;
credentialsShouldBeDeletedAtTime?: number;
}
export interface RemotelySavePluginSettings {
@ -71,3 +73,6 @@ export interface UriParams {
ver?: string;
data?: string;
}
// 80 days
export const OAUTH2_FORCE_EXPIRE_MILLISECONDS = 1000 * 60 * 60 * 24 * 80;

View File

@ -1,4 +1,5 @@
import { Modal, Notice, Plugin, Setting } from "obsidian";
import cloneDeep from "lodash/cloneDeep";
import type { RemotelySavePluginSettings } from "./baseTypes";
import {
COMMAND_CALLBACK,
@ -20,12 +21,13 @@ import {
DEFAULT_DROPBOX_CONFIG,
getAuthUrlAndVerifier as getAuthUrlAndVerifierDropbox,
sendAuthReq as sendAuthReqDropbox,
setConfigBySuccessfullAuthInplace,
setConfigBySuccessfullAuthInplace as setConfigBySuccessfullAuthInplaceDropbox,
} from "./remoteForDropbox";
import {
AccessCodeResponseSuccessfulType,
DEFAULT_ONEDRIVE_CONFIG,
sendAuthReq as sendAuthReqOnedrive,
setConfigBySuccessfullAuthInplace as setConfigBySuccessfullAuthInplaceOnedrive,
} from "./remoteForOnedrive";
import { DEFAULT_S3_CONFIG } from "./remoteForS3";
import { DEFAULT_WEBDAV_CONFIG } from "./remoteForWebdav";
@ -69,6 +71,7 @@ export default class RemotelySavePlugin extends Plugin {
}; // init
await this.loadSettings();
await this.checkIfOauthExpires();
await this.prepareDB();
@ -91,7 +94,7 @@ export default class RemotelySavePlugin extends Plugin {
if (parsed.status === "error") {
new Notice(parsed.message);
} else {
const copied = JSON.parse(JSON.stringify(parsed.result));
const copied = cloneDeep(parsed.result);
// new Notice(JSON.stringify(copied))
this.settings = copied;
this.saveSettings();
@ -133,7 +136,7 @@ export default class RemotelySavePlugin extends Plugin {
);
const self = this;
setConfigBySuccessfullAuthInplace(
setConfigBySuccessfullAuthInplaceDropbox(
this.settings.dropbox,
authRes,
() => self.saveSettings()
@ -212,15 +215,13 @@ export default class RemotelySavePlugin extends Plugin {
throw Error(`${JSON.stringify(rsp)}`);
}
rsp = rsp as AccessCodeResponseSuccessfulType;
this.settings.onedrive.accessToken = rsp.access_token;
this.settings.onedrive.accessTokenExpiresAtTime =
Date.now() + rsp.expires_in - 5 * 60 * 1000;
this.settings.onedrive.accessTokenExpiresInSeconds = rsp.expires_in;
this.settings.onedrive.refreshToken = rsp.refresh_token;
await this.saveSettings();
const self = this;
setConfigBySuccessfullAuthInplaceOnedrive(
this.settings.onedrive,
rsp as AccessCodeResponseSuccessfulType,
() => self.saveSettings()
);
const client = new RemoteClient(
"onedrive",
undefined,
@ -372,7 +373,7 @@ export default class RemotelySavePlugin extends Plugin {
async loadSettings() {
this.settings = Object.assign(
{},
JSON.parse(JSON.stringify(DEFAULT_SETTINGS)) /* copy an object */,
cloneDeep(DEFAULT_SETTINGS),
await this.loadData()
);
if (this.settings.dropbox.clientID === "") {
@ -390,6 +391,76 @@ export default class RemotelySavePlugin extends Plugin {
await this.saveData(this.settings);
}
async checkIfOauthExpires() {
let needSave: boolean = false;
const current = Date.now();
// fullfill old version settings
if (
this.settings.dropbox.refreshToken !== "" &&
this.settings.dropbox.credentialsShouldBeDeletedAtTime === undefined
) {
// It has a refreshToken, but not expire time.
// Likely to be a setting from old version.
// we set it to a month.
this.settings.dropbox.credentialsShouldBeDeletedAtTime =
current + 1000 * 60 * 60 * 24 * 30;
needSave = true;
}
if (
this.settings.onedrive.refreshToken !== "" &&
this.settings.onedrive.credentialsShouldBeDeletedAtTime === undefined
) {
this.settings.onedrive.credentialsShouldBeDeletedAtTime =
current + 1000 * 60 * 60 * 24 * 30;
needSave = true;
}
// check expired or not
let dropboxExpired = false;
if (
this.settings.dropbox.refreshToken !== "" &&
current >= this.settings.dropbox.credentialsShouldBeDeletedAtTime
) {
dropboxExpired = true;
this.settings.dropbox = cloneDeep(DEFAULT_DROPBOX_CONFIG);
needSave = true;
}
let onedriveExpired = false;
if (
this.settings.onedrive.refreshToken !== "" &&
current >= this.settings.onedrive.credentialsShouldBeDeletedAtTime
) {
onedriveExpired = true;
this.settings.onedrive = cloneDeep(DEFAULT_ONEDRIVE_CONFIG);
needSave = true;
}
// save back
if (needSave) {
await this.saveSettings();
}
// send notice
if (dropboxExpired && onedriveExpired) {
new Notice(
`${this.manifest.name}: You haven't manually auth Dropbox and OneDrive for a while, you need to re-auth them again.`,
6000
);
} else if (dropboxExpired) {
new Notice(
`${this.manifest.name}: You haven't manually auth Dropbox for a while, you need to re-auth it again.`,
6000
);
} else if (onedriveExpired) {
new Notice(
`${this.manifest.name}: You haven't manually auth OneDrive for a while, you need to re-auth it again.`,
6000
);
}
}
async prepareDB() {
this.db = await prepareDBs();
}

View File

@ -5,13 +5,14 @@ import {
DropboxConfig,
RemoteItem,
COMMAND_CALLBACK_DROPBOX,
OAUTH2_FORCE_EXPIRE_MILLISECONDS,
} from "./baseTypes";
import { decryptArrayBuffer, encryptArrayBuffer } from "./encrypt";
import { bufferToArrayBuffer, getFolderLevels, mkdirpInVault } from "./misc";
export { Dropbox } from "dropbox";
export const DEFAULT_DROPBOX_CONFIG = {
export const DEFAULT_DROPBOX_CONFIG: DropboxConfig = {
accessToken: "",
clientID: process.env.DEFAULT_DROPBOX_APP_KEY,
refreshToken: "",
@ -19,6 +20,7 @@ export const DEFAULT_DROPBOX_CONFIG = {
accessTokenExpiresAtTime: 0,
accountID: "",
username: "",
credentialsShouldBeDeletedAtTime: 0,
};
export const getDropboxPath = (fileOrFolderPath: string, vaultName: string) => {
@ -232,6 +234,10 @@ export const setConfigBySuccessfullAuthInplace = async (
config.accessTokenExpiresAtTime =
Date.now() + parseInt(authRes.expires_in) * 1000 - 10 * 1000;
// manually set it expired after 80 days;
config.credentialsShouldBeDeletedAtTime =
Date.now() + OAUTH2_FORCE_EXPIRE_MILLISECONDS;
if (authRes.refresh_token !== undefined) {
config.refreshToken = authRes.refresh_token;
}

View File

@ -11,9 +11,15 @@ import {
UploadResult,
} from "@microsoft/microsoft-graph-client";
import type { DriveItem, User } from "@microsoft/microsoft-graph-types";
import cloneDeep from "lodash/cloneDeep";
import { request, Vault } from "obsidian";
import * as path from "path";
import type { OnedriveConfig, RemoteItem } from "./baseTypes";
import {
DropboxConfig,
OAUTH2_FORCE_EXPIRE_MILLISECONDS,
OnedriveConfig,
RemoteItem,
} from "./baseTypes";
import { COMMAND_CALLBACK_ONEDRIVE } from "./baseTypes";
import { decryptArrayBuffer, encryptArrayBuffer } from "./encrypt";
import {
@ -34,6 +40,7 @@ export const DEFAULT_ONEDRIVE_CONFIG: OnedriveConfig = {
accessTokenExpiresAtTime: 0,
deltaLink: "",
username: "",
credentialsShouldBeDeletedAtTime: 0,
};
////////////////////////////////////////////////////////////////////////////////
@ -173,6 +180,29 @@ export const sendRefreshTokenReq = async (
}
};
export const setConfigBySuccessfullAuthInplace = async (
config: OnedriveConfig,
authRes: AccessCodeResponseSuccessfulType,
saveUpdatedConfigFunc: () => Promise<any> | undefined
) => {
console.log("start updating local info of OneDrive token");
config.accessToken = authRes.access_token;
config.accessTokenExpiresAtTime =
Date.now() + authRes.expires_in - 5 * 60 * 1000;
config.accessTokenExpiresInSeconds = authRes.expires_in;
config.refreshToken = authRes.refresh_token;
// manually set it expired after 80 days;
config.credentialsShouldBeDeletedAtTime =
Date.now() + OAUTH2_FORCE_EXPIRE_MILLISECONDS;
if (saveUpdatedConfigFunc !== undefined) {
await saveUpdatedConfigFunc();
}
console.log("finish updating local info of Onedrive token");
};
////////////////////////////////////////////////////////////////////////////////
// Other usual common methods
////////////////////////////////////////////////////////////////////////////////
@ -405,7 +435,7 @@ export const listFromRemote = async (
while (NEXT_LINK_KEY in res) {
res = await client.client.api(res[NEXT_LINK_KEY]).get();
driveItems.push(...JSON.parse(JSON.stringify(res.value as DriveItem[])));
driveItems.push(...cloneDeep(res.value as DriveItem[]));
}
// lastly we should have delta link?