mirror of https://github.com/veypi/OneAuth.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
5.1 KiB
TypeScript
181 lines
5.1 KiB
TypeScript
/*
|
|
* fs.ts
|
|
* Copyright (C) 2023 veypi <i@veypi.com>
|
|
* 2023-10-08 01:55
|
|
* Distributed under terms of the MIT license.
|
|
*/
|
|
|
|
|
|
import * as webdav from 'webdav'
|
|
export { type FileStat } from 'webdav'
|
|
import { proxy } from "./v2dom";
|
|
import logic from "./logic";
|
|
|
|
function delay(ms: number) {
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
}
|
|
|
|
class davWraper {
|
|
private client: webdav.WebDAVClient
|
|
private host: string
|
|
private prefix: string
|
|
private token: string
|
|
constructor(host: string, prefix: string, token: string) {
|
|
this.host = host
|
|
this.prefix = prefix
|
|
this.token = token
|
|
this.client = webdav.createClient(this.host + this.prefix)
|
|
this.set(host, prefix, token)
|
|
}
|
|
set(host: string, prefix: string, token: string) {
|
|
this.host = host
|
|
this.prefix = prefix
|
|
this.token = token
|
|
this.client = webdav.createClient(this.host + this.prefix)
|
|
if (this.prefix.endsWith('/')) {
|
|
this.prefix = this.prefix.slice(0, -1)
|
|
}
|
|
this.client.setHeaders({
|
|
authorization: "bearer " + this.token
|
|
})
|
|
}
|
|
putFileContents(filename: string, data: string | webdav.BufferLike, options?: webdav.PutFileContentsOptions) {
|
|
return this.retry(() => this.client.putFileContents(filename, data, options))
|
|
}
|
|
getFileContents(filename: string, options?: webdav.GetFileContentsOptions) {
|
|
return this.retry(() => this.client.getFileContents(filename, options))
|
|
}
|
|
getDirectoryContents(path: string, options?: webdav.GetDirectoryContentsOptions) {
|
|
return this.retry(() => this.client.getDirectoryContents(path, options))
|
|
}
|
|
stat(path: string, options?: webdav.StatOptions) {
|
|
return this.retry(() => this.client.stat(path, options))
|
|
}
|
|
urlwrap(path: string) {
|
|
if (path.startsWith('/')) {
|
|
return this.prefix + path
|
|
} else {
|
|
return this.prefix + '/' + path
|
|
}
|
|
}
|
|
urlunwrap(url: string) {
|
|
if (url.startsWith(this.prefix)) {
|
|
return url.slice(this.prefix.length)
|
|
}
|
|
return url
|
|
}
|
|
private retry<T>(fn: () => Promise<T>): Promise<T> {
|
|
let retries = 0;
|
|
function attempt(): Promise<T> {
|
|
return fn().catch(error => {
|
|
console.log(error.status)
|
|
if (retries < 3) {
|
|
retries++;
|
|
console.log(`Attempt ${retries} failed, retrying after 1 second...`);
|
|
return delay(1000).then(attempt);
|
|
} else {
|
|
// 超过最大重试次数后不再重试
|
|
throw error;
|
|
}
|
|
})
|
|
}
|
|
return attempt()
|
|
}
|
|
}
|
|
|
|
let token = logic.token.oa.raw()
|
|
const user = new davWraper(logic.Host(), '/fs/u/' + logic.token.refresh.uid, token)
|
|
const app = new davWraper(logic.Host(), '/fs/a/' + logic.oa_id, token)
|
|
|
|
|
|
const sync = () => {
|
|
if (logic.token.oa.isVaild()) {
|
|
let t = logic.token.oa.raw()
|
|
// console.warn('sync oafs token: ' + t)
|
|
user.set(logic.Host(), '/fs/u/' + logic.token.refresh.uid, t)
|
|
app.set(logic.Host(), '/fs/a/' + logic.app_id, t)
|
|
}
|
|
}
|
|
proxy.Listen(() => {
|
|
sync()
|
|
})
|
|
|
|
const rename = (o: string, n?: string) => {
|
|
let ext = '.' + o.split('.').pop()?.toLowerCase()
|
|
if (n) {
|
|
return n + ext
|
|
}
|
|
const d = performance.now().toString(36);
|
|
return d + ext
|
|
}
|
|
|
|
|
|
// const get = (url: string): Promise<string> => {
|
|
// return fetch(cfg.Host() + url, { headers: { authorization: "bearer " + cfg.oa_token.value } }).then((response) => response.text())
|
|
// }
|
|
|
|
// rename 可以保持url不变
|
|
// const upload = (f: FileList | File[], dir?: string, renames?: string[]) => {
|
|
// return new Promise<string[]>((resolve, reject) => {
|
|
// var data = new FormData();
|
|
// for (let i = 0; i < f.length; i++) {
|
|
// let nf = new File([f[i]], rename(f[i].name, renames && renames[i] ? renames[i] : undefined), { type: f[i].type })
|
|
// data.append('files', nf, nf.name)
|
|
// }
|
|
// axios.post("/api/upload/" + (dir || ''), data, {
|
|
// headers: {
|
|
// "Content-Type": 'multipart/form-data',
|
|
// 'auth_token': cfg.oa_token.value,
|
|
// }
|
|
// }).then(e => {
|
|
// resolve(e.data)
|
|
// }).catch(reject)
|
|
// })
|
|
// }
|
|
|
|
const get_dav = (client: webdav.WebDAVClient, base_url: string) => {
|
|
return {
|
|
client: client,
|
|
stat: client.stat,
|
|
dir: client.getDirectoryContents,
|
|
uploadstr: (dir: string, name: string, data: string) => {
|
|
if (dir.startsWith('/')) {
|
|
dir = dir.slice(1)
|
|
}
|
|
return new Promise((resolve, reject) => {
|
|
let temp = () => {
|
|
let reader = new FileReader()
|
|
reader.onload = function (event) {
|
|
var res = event.target?.result
|
|
// let data = new Blob([res])
|
|
client.putFileContents(dir + name, res).then(e => {
|
|
if (e) {
|
|
resolve(base_url + dir + name)
|
|
}
|
|
}).catch(reject)
|
|
}
|
|
reader.readAsArrayBuffer(new Blob([data], { type: 'plain/text' }))
|
|
}
|
|
client.stat(dir).then(() => {
|
|
temp()
|
|
}).catch((_) => {
|
|
client.createDirectory(dir, { recursive: true }).then(() => {
|
|
temp()
|
|
}).catch(e => {
|
|
console.warn(e)
|
|
})
|
|
})
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export default {
|
|
user,
|
|
app,
|
|
rename,
|
|
}
|
|
|