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.
		
		
		
		
		
			
		
			
	
	
		
			98 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			TypeScript
		
	
		
		
			
		
	
	
			98 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			TypeScript
		
	
| 
											9 months ago
										 | import { STORAGE_KEY } from "@/app/constant"; | ||
|  | import { SyncStore } from "@/app/store/sync"; | ||
|  | 
 | ||
|  | export type WebDAVConfig = SyncStore["webdav"]; | ||
|  | export type WebDavClient = ReturnType<typeof createWebDavClient>; | ||
|  | 
 | ||
|  | export function createWebDavClient(store: SyncStore) { | ||
|  |   const folder = STORAGE_KEY; | ||
|  |   const fileName = `${folder}/backup.json`; | ||
|  |   const config = store.webdav; | ||
|  |   const proxyUrl = | ||
|  |     store.useProxy && store.proxyUrl.length > 0 ? store.proxyUrl : undefined; | ||
|  | 
 | ||
|  |   return { | ||
|  |     async check() { | ||
|  |       try { | ||
|  |         const res = await fetch(this.path(folder, proxyUrl, "MKCOL"), { | ||
|  |           method: "GET", | ||
|  |           headers: this.headers(), | ||
|  |         }); | ||
|  |         const success = [201, 200, 404, 405, 301, 302, 307, 308].includes( | ||
|  |           res.status, | ||
|  |         ); | ||
|  |         console.log( | ||
|  |           `[WebDav] check ${success ? "success" : "failed"}, ${res.status} ${ | ||
|  |             res.statusText | ||
|  |           }`,
 | ||
|  |         ); | ||
|  |         return success; | ||
|  |       } catch (e) { | ||
|  |         console.error("[WebDav] failed to check", e); | ||
|  |       } | ||
|  | 
 | ||
|  |       return false; | ||
|  |     }, | ||
|  | 
 | ||
|  |     async get(key: string) { | ||
|  |       const res = await fetch(this.path(fileName, proxyUrl), { | ||
|  |         method: "GET", | ||
|  |         headers: this.headers(), | ||
|  |       }); | ||
|  | 
 | ||
|  |       console.log("[WebDav] get key = ", key, res.status, res.statusText); | ||
|  | 
 | ||
|  |       if (404 == res.status) { | ||
|  |         return ""; | ||
|  |       } | ||
|  | 
 | ||
|  |       return await res.text(); | ||
|  |     }, | ||
|  | 
 | ||
|  |     async set(key: string, value: string) { | ||
|  |       const res = await fetch(this.path(fileName, proxyUrl), { | ||
|  |         method: "PUT", | ||
|  |         headers: this.headers(), | ||
|  |         body: value, | ||
|  |       }); | ||
|  | 
 | ||
|  |       console.log("[WebDav] set key = ", key, res.status, res.statusText); | ||
|  |     }, | ||
|  | 
 | ||
|  |     headers() { | ||
|  |       const auth = btoa(config.username + ":" + config.password); | ||
|  | 
 | ||
|  |       return { | ||
|  |         authorization: `Basic ${auth}`, | ||
|  |       }; | ||
|  |     }, | ||
|  |     path(path: string, proxyUrl: string = "", proxyMethod: string = "") { | ||
|  |       if (path.startsWith("/")) { | ||
|  |         path = path.slice(1); | ||
|  |       } | ||
|  | 
 | ||
|  |       if (proxyUrl.endsWith("/")) { | ||
|  |         proxyUrl = proxyUrl.slice(0, -1); | ||
|  |       } | ||
|  | 
 | ||
|  |       let url; | ||
|  |       const pathPrefix = "/api/webdav/"; | ||
|  | 
 | ||
|  |       try { | ||
|  |         let u = new URL(proxyUrl + pathPrefix + path); | ||
|  |         // add query params
 | ||
|  |         u.searchParams.append("endpoint", config.endpoint); | ||
|  |         proxyMethod && u.searchParams.append("proxy_method", proxyMethod); | ||
|  |         url = u.toString(); | ||
|  |       } catch (e) { | ||
|  |         url = pathPrefix + path + "?endpoint=" + config.endpoint; | ||
|  |         if (proxyMethod) { | ||
|  |           url += "&proxy_method=" + proxyMethod; | ||
|  |         } | ||
|  |       } | ||
|  | 
 | ||
|  |       return url; | ||
|  |     }, | ||
|  |   }; | ||
|  | } |