force expire login cred
This commit is contained in:
parent
34d1b01c7b
commit
6832c9f649
@ -25,6 +25,7 @@
|
|||||||
"@types/chai": "^4.2.22",
|
"@types/chai": "^4.2.22",
|
||||||
"@types/chai-as-promised": "^7.1.4",
|
"@types/chai-as-promised": "^7.1.4",
|
||||||
"@types/jsdom": "^16.2.13",
|
"@types/jsdom": "^16.2.13",
|
||||||
|
"@types/lodash": "^4.14.178",
|
||||||
"@types/mime-types": "^2.1.1",
|
"@types/mime-types": "^2.1.1",
|
||||||
"@types/mocha": "^9.0.0",
|
"@types/mocha": "^9.0.0",
|
||||||
"@types/node": "^14.14.37",
|
"@types/node": "^14.14.37",
|
||||||
@ -60,6 +61,7 @@
|
|||||||
"crypto-browserify": "^3.12.0",
|
"crypto-browserify": "^3.12.0",
|
||||||
"dropbox": "^10.22.0",
|
"dropbox": "^10.22.0",
|
||||||
"localforage": "^1.10.0",
|
"localforage": "^1.10.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"mime-types": "^2.1.33",
|
"mime-types": "^2.1.33",
|
||||||
"obsidian": "^0.12.0",
|
"obsidian": "^0.12.0",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
|
|||||||
@ -21,6 +21,7 @@ export interface DropboxConfig {
|
|||||||
accessTokenExpiresAtTime: number;
|
accessTokenExpiresAtTime: number;
|
||||||
accountID: string;
|
accountID: string;
|
||||||
username: string;
|
username: string;
|
||||||
|
credentialsShouldBeDeletedAtTime?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WebdavAuthType = "digest" | "basic";
|
export type WebdavAuthType = "digest" | "basic";
|
||||||
@ -41,6 +42,7 @@ export interface OnedriveConfig {
|
|||||||
accessTokenExpiresAtTime: number;
|
accessTokenExpiresAtTime: number;
|
||||||
deltaLink: string;
|
deltaLink: string;
|
||||||
username: string;
|
username: string;
|
||||||
|
credentialsShouldBeDeletedAtTime?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RemotelySavePluginSettings {
|
export interface RemotelySavePluginSettings {
|
||||||
@ -71,3 +73,6 @@ export interface UriParams {
|
|||||||
ver?: string;
|
ver?: string;
|
||||||
data?: string;
|
data?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 80 days
|
||||||
|
export const OAUTH2_FORCE_EXPIRE_MILLISECONDS = 1000 * 60 * 60 * 24 * 80;
|
||||||
|
|||||||
95
src/main.ts
95
src/main.ts
@ -1,4 +1,5 @@
|
|||||||
import { Modal, Notice, Plugin, Setting } from "obsidian";
|
import { Modal, Notice, Plugin, Setting } from "obsidian";
|
||||||
|
import cloneDeep from "lodash/cloneDeep";
|
||||||
import type { RemotelySavePluginSettings } from "./baseTypes";
|
import type { RemotelySavePluginSettings } from "./baseTypes";
|
||||||
import {
|
import {
|
||||||
COMMAND_CALLBACK,
|
COMMAND_CALLBACK,
|
||||||
@ -20,12 +21,13 @@ import {
|
|||||||
DEFAULT_DROPBOX_CONFIG,
|
DEFAULT_DROPBOX_CONFIG,
|
||||||
getAuthUrlAndVerifier as getAuthUrlAndVerifierDropbox,
|
getAuthUrlAndVerifier as getAuthUrlAndVerifierDropbox,
|
||||||
sendAuthReq as sendAuthReqDropbox,
|
sendAuthReq as sendAuthReqDropbox,
|
||||||
setConfigBySuccessfullAuthInplace,
|
setConfigBySuccessfullAuthInplace as setConfigBySuccessfullAuthInplaceDropbox,
|
||||||
} from "./remoteForDropbox";
|
} from "./remoteForDropbox";
|
||||||
import {
|
import {
|
||||||
AccessCodeResponseSuccessfulType,
|
AccessCodeResponseSuccessfulType,
|
||||||
DEFAULT_ONEDRIVE_CONFIG,
|
DEFAULT_ONEDRIVE_CONFIG,
|
||||||
sendAuthReq as sendAuthReqOnedrive,
|
sendAuthReq as sendAuthReqOnedrive,
|
||||||
|
setConfigBySuccessfullAuthInplace as setConfigBySuccessfullAuthInplaceOnedrive,
|
||||||
} from "./remoteForOnedrive";
|
} from "./remoteForOnedrive";
|
||||||
import { DEFAULT_S3_CONFIG } from "./remoteForS3";
|
import { DEFAULT_S3_CONFIG } from "./remoteForS3";
|
||||||
import { DEFAULT_WEBDAV_CONFIG } from "./remoteForWebdav";
|
import { DEFAULT_WEBDAV_CONFIG } from "./remoteForWebdav";
|
||||||
@ -69,6 +71,7 @@ export default class RemotelySavePlugin extends Plugin {
|
|||||||
}; // init
|
}; // init
|
||||||
|
|
||||||
await this.loadSettings();
|
await this.loadSettings();
|
||||||
|
await this.checkIfOauthExpires();
|
||||||
|
|
||||||
await this.prepareDB();
|
await this.prepareDB();
|
||||||
|
|
||||||
@ -91,7 +94,7 @@ export default class RemotelySavePlugin extends Plugin {
|
|||||||
if (parsed.status === "error") {
|
if (parsed.status === "error") {
|
||||||
new Notice(parsed.message);
|
new Notice(parsed.message);
|
||||||
} else {
|
} else {
|
||||||
const copied = JSON.parse(JSON.stringify(parsed.result));
|
const copied = cloneDeep(parsed.result);
|
||||||
// new Notice(JSON.stringify(copied))
|
// new Notice(JSON.stringify(copied))
|
||||||
this.settings = copied;
|
this.settings = copied;
|
||||||
this.saveSettings();
|
this.saveSettings();
|
||||||
@ -133,7 +136,7 @@ export default class RemotelySavePlugin extends Plugin {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
setConfigBySuccessfullAuthInplace(
|
setConfigBySuccessfullAuthInplaceDropbox(
|
||||||
this.settings.dropbox,
|
this.settings.dropbox,
|
||||||
authRes,
|
authRes,
|
||||||
() => self.saveSettings()
|
() => self.saveSettings()
|
||||||
@ -212,15 +215,13 @@ export default class RemotelySavePlugin extends Plugin {
|
|||||||
throw Error(`${JSON.stringify(rsp)}`);
|
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;
|
const self = this;
|
||||||
|
setConfigBySuccessfullAuthInplaceOnedrive(
|
||||||
|
this.settings.onedrive,
|
||||||
|
rsp as AccessCodeResponseSuccessfulType,
|
||||||
|
() => self.saveSettings()
|
||||||
|
);
|
||||||
|
|
||||||
const client = new RemoteClient(
|
const client = new RemoteClient(
|
||||||
"onedrive",
|
"onedrive",
|
||||||
undefined,
|
undefined,
|
||||||
@ -372,7 +373,7 @@ export default class RemotelySavePlugin extends Plugin {
|
|||||||
async loadSettings() {
|
async loadSettings() {
|
||||||
this.settings = Object.assign(
|
this.settings = Object.assign(
|
||||||
{},
|
{},
|
||||||
JSON.parse(JSON.stringify(DEFAULT_SETTINGS)) /* copy an object */,
|
cloneDeep(DEFAULT_SETTINGS),
|
||||||
await this.loadData()
|
await this.loadData()
|
||||||
);
|
);
|
||||||
if (this.settings.dropbox.clientID === "") {
|
if (this.settings.dropbox.clientID === "") {
|
||||||
@ -390,6 +391,76 @@ export default class RemotelySavePlugin extends Plugin {
|
|||||||
await this.saveData(this.settings);
|
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() {
|
async prepareDB() {
|
||||||
this.db = await prepareDBs();
|
this.db = await prepareDBs();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,13 +5,14 @@ import {
|
|||||||
DropboxConfig,
|
DropboxConfig,
|
||||||
RemoteItem,
|
RemoteItem,
|
||||||
COMMAND_CALLBACK_DROPBOX,
|
COMMAND_CALLBACK_DROPBOX,
|
||||||
|
OAUTH2_FORCE_EXPIRE_MILLISECONDS,
|
||||||
} from "./baseTypes";
|
} from "./baseTypes";
|
||||||
import { decryptArrayBuffer, encryptArrayBuffer } from "./encrypt";
|
import { decryptArrayBuffer, encryptArrayBuffer } from "./encrypt";
|
||||||
import { bufferToArrayBuffer, getFolderLevels, mkdirpInVault } from "./misc";
|
import { bufferToArrayBuffer, getFolderLevels, mkdirpInVault } from "./misc";
|
||||||
|
|
||||||
export { Dropbox } from "dropbox";
|
export { Dropbox } from "dropbox";
|
||||||
|
|
||||||
export const DEFAULT_DROPBOX_CONFIG = {
|
export const DEFAULT_DROPBOX_CONFIG: DropboxConfig = {
|
||||||
accessToken: "",
|
accessToken: "",
|
||||||
clientID: process.env.DEFAULT_DROPBOX_APP_KEY,
|
clientID: process.env.DEFAULT_DROPBOX_APP_KEY,
|
||||||
refreshToken: "",
|
refreshToken: "",
|
||||||
@ -19,6 +20,7 @@ export const DEFAULT_DROPBOX_CONFIG = {
|
|||||||
accessTokenExpiresAtTime: 0,
|
accessTokenExpiresAtTime: 0,
|
||||||
accountID: "",
|
accountID: "",
|
||||||
username: "",
|
username: "",
|
||||||
|
credentialsShouldBeDeletedAtTime: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDropboxPath = (fileOrFolderPath: string, vaultName: string) => {
|
export const getDropboxPath = (fileOrFolderPath: string, vaultName: string) => {
|
||||||
@ -232,6 +234,10 @@ export const setConfigBySuccessfullAuthInplace = async (
|
|||||||
config.accessTokenExpiresAtTime =
|
config.accessTokenExpiresAtTime =
|
||||||
Date.now() + parseInt(authRes.expires_in) * 1000 - 10 * 1000;
|
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) {
|
if (authRes.refresh_token !== undefined) {
|
||||||
config.refreshToken = authRes.refresh_token;
|
config.refreshToken = authRes.refresh_token;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,9 +11,15 @@ import {
|
|||||||
UploadResult,
|
UploadResult,
|
||||||
} from "@microsoft/microsoft-graph-client";
|
} from "@microsoft/microsoft-graph-client";
|
||||||
import type { DriveItem, User } from "@microsoft/microsoft-graph-types";
|
import type { DriveItem, User } from "@microsoft/microsoft-graph-types";
|
||||||
|
import cloneDeep from "lodash/cloneDeep";
|
||||||
import { request, Vault } from "obsidian";
|
import { request, Vault } from "obsidian";
|
||||||
import * as path from "path";
|
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 { COMMAND_CALLBACK_ONEDRIVE } from "./baseTypes";
|
||||||
import { decryptArrayBuffer, encryptArrayBuffer } from "./encrypt";
|
import { decryptArrayBuffer, encryptArrayBuffer } from "./encrypt";
|
||||||
import {
|
import {
|
||||||
@ -34,6 +40,7 @@ export const DEFAULT_ONEDRIVE_CONFIG: OnedriveConfig = {
|
|||||||
accessTokenExpiresAtTime: 0,
|
accessTokenExpiresAtTime: 0,
|
||||||
deltaLink: "",
|
deltaLink: "",
|
||||||
username: "",
|
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
|
// Other usual common methods
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -405,7 +435,7 @@ export const listFromRemote = async (
|
|||||||
|
|
||||||
while (NEXT_LINK_KEY in res) {
|
while (NEXT_LINK_KEY in res) {
|
||||||
res = await client.client.api(res[NEXT_LINK_KEY]).get();
|
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?
|
// lastly we should have delta link?
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user