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
		
	
| 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;
 | |
|     },
 | |
|   };
 | |
| }
 |