mirror of
https://github.com/trevor1969/teatracker.git
synced 2026-08-09 10:41:59 +00:00
fix: Add CORS proxy fallback for Nextcloud WebDAV connections
- Add corsproxy.io as fallback for CORS-restricted WebDAV requests - Add fetchWithProxy wrapper method to NextcloudStorage class - Update all NextcloudStorage methods to use proxy fallback - Proxy is automatically used when direct connection fails - Add useProxy flag to track proxy usage This fixes the 'NetworkError when attempting to fetch resource' issue caused by CORS restrictions when accessing Nextcloud from file:// or different domains. Generated by Vibe Code Co-authored-by: trevor1969 <trevor1969@users.noreply.github.com>
This commit is contained in:
72
app.js
72
app.js
@ -1,4 +1,16 @@
|
||||
// TeeTracker - Main Application with Nextcloud Support
|
||||
// Nextcloud Storage Integration
|
||||
// ============================================
|
||||
|
||||
class NextcloudStorage {
|
||||
=======
|
||||
// ============================================
|
||||
// Nextcloud Storage Integration
|
||||
// ============================================
|
||||
|
||||
// CORS Proxy for Nextcloud WebDAV (fallback when direct connection fails due to CORS)
|
||||
const NEXTCLOUD_PROXY = 'https://corsproxy.io/?';
|
||||
|
||||
class NextcloudStorage {TeeTracker - Main Application with Nextcloud Support
|
||||
|
||||
// ============================================
|
||||
// Configuration
|
||||
@ -21,6 +33,7 @@ class NextcloudStorage {
|
||||
this.authHeader = 'Basic ' + btoa(`${username}:${password}`);
|
||||
this.connected = false;
|
||||
this.lastError = null;
|
||||
this.useProxy = false;
|
||||
}
|
||||
|
||||
getFileUrl(filename) {
|
||||
@ -31,9 +44,54 @@ class NextcloudStorage {
|
||||
return `${this.baseUrl}/remote.php/dav/files/${encodeURIComponent(this.username)}${this.path}`;
|
||||
}
|
||||
|
||||
// Get proxied URL for CORS fallback
|
||||
getProxiedUrl(url) {
|
||||
return `${NEXTCLOUD_PROXY}${encodeURIComponent(url)}`;
|
||||
}
|
||||
|
||||
// Wrapper for fetch that automatically uses proxy on CORS failure
|
||||
async fetchWithProxy(url, options = {}) {
|
||||
try {
|
||||
// First try direct connection
|
||||
const response = await fetch(url, options);
|
||||
|
||||
// If we get a CORS error or network error, it will throw
|
||||
// If we get here, the request succeeded (even if status is not 2xx)
|
||||
if (response.ok || response.status === 404 || response.status === 405) {
|
||||
this.useProxy = false;
|
||||
return response;
|
||||
}
|
||||
|
||||
// Some errors might still occur, so try proxy
|
||||
console.log('Direct connection returned non-ok status, trying proxy...');
|
||||
} catch (error) {
|
||||
// Direct connection failed (CORS or network error), try proxy
|
||||
console.log('Direct connection failed, trying proxy...');
|
||||
}
|
||||
|
||||
// Try with proxy
|
||||
try {
|
||||
const proxyUrl = this.getProxiedUrl(url);
|
||||
this.useProxy = true;
|
||||
const response = await fetch(proxyUrl, options);
|
||||
|
||||
if (response.ok || response.status === 404 || response.status === 405) {
|
||||
console.log('Proxy connection successful');
|
||||
return response;
|
||||
}
|
||||
|
||||
// If proxy also fails, throw error
|
||||
throw new Error(`Proxy returned status: ${response.status}`);
|
||||
} catch (proxyError) {
|
||||
this.useProxy = false;
|
||||
console.error('Proxy connection also failed:', proxyError);
|
||||
throw new Error(`Both direct and proxy connections failed: ${error.message || ''} ${proxyError.message || ''}`);
|
||||
}
|
||||
}
|
||||
|
||||
async testConnection() {
|
||||
try {
|
||||
const response = await fetch(this.getDirectoryUrl(), {
|
||||
const response = await this.fetchWithProxy(this.getDirectoryUrl(), {
|
||||
method: 'PROPFIND',
|
||||
headers: {
|
||||
'Authorization': this.authHeader,
|
||||
@ -65,7 +123,7 @@ class NextcloudStorage {
|
||||
|
||||
async ensureDirectory() {
|
||||
try {
|
||||
const response = await fetch(this.getDirectoryUrl(), {
|
||||
const response = await this.fetchWithProxy(this.getDirectoryUrl(), {
|
||||
method: 'MKCOL',
|
||||
headers: { 'Authorization': this.authHeader }
|
||||
});
|
||||
@ -80,7 +138,7 @@ class NextcloudStorage {
|
||||
async ensureSubDirectory(subPath) {
|
||||
try {
|
||||
const subDirUrl = `${this.getDirectoryUrl()}${subPath}/`;
|
||||
const response = await fetch(subDirUrl, {
|
||||
const response = await this.fetchWithProxy(subDirUrl, {
|
||||
method: 'MKCOL',
|
||||
headers: { 'Authorization': this.authHeader }
|
||||
});
|
||||
@ -94,7 +152,7 @@ class NextcloudStorage {
|
||||
async loadFile(filename) {
|
||||
try {
|
||||
const url = this.getFileUrl(filename);
|
||||
const response = await fetch(url, {
|
||||
const response = await this.fetchWithProxy(url, {
|
||||
headers: { 'Authorization': this.authHeader }
|
||||
});
|
||||
|
||||
@ -114,7 +172,7 @@ class NextcloudStorage {
|
||||
async saveFile(filename, data) {
|
||||
try {
|
||||
const url = this.getFileUrl(filename);
|
||||
const response = await fetch(url, {
|
||||
const response = await this.fetchWithProxy(url, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Authorization': this.authHeader,
|
||||
@ -132,7 +190,7 @@ class NextcloudStorage {
|
||||
async fileExists(filename) {
|
||||
try {
|
||||
const url = this.getFileUrl(filename);
|
||||
const response = await fetch(url, {
|
||||
const response = await this.fetchWithProxy(url, {
|
||||
method: 'HEAD',
|
||||
headers: { 'Authorization': this.authHeader }
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user