UNPKG

@mvp-factory/holy-auth-firebase

Version:

Firebase Authentication module with Google Sign-In support

133 lines (132 loc) 4.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.authenticatedFetch = authenticatedFetch; exports.authenticatedJSON = authenticatedJSON; exports.authenticatedPost = authenticatedPost; exports.authenticatedGet = authenticatedGet; exports.authenticatedDelete = authenticatedDelete; exports.authenticatedPut = authenticatedPut; exports.authenticatedPatch = authenticatedPatch; exports.authenticatedUpload = authenticatedUpload; exports.createAuthenticatedClient = createAuthenticatedClient; const FirebaseAuthManager_1 = require("../core/FirebaseAuthManager"); async function authenticatedFetch(url, options = {}) { const { skipAuth = false, forceTokenRefresh = false, retryOnUnauthorized = true, maxRetries = 1, ...fetchOptions } = options; if (skipAuth) { return fetch(url, fetchOptions); } const authManager = FirebaseAuthManager_1.FirebaseAuthManager.getInstance(); const token = await authManager.getIdToken(forceTokenRefresh); if (!token) { throw new Error('Not authenticated'); } const headers = { ...fetchOptions.headers, 'Authorization': `Bearer ${token}` }; let lastError = null; let retryCount = 0; while (retryCount <= maxRetries) { try { const response = await fetch(url, { ...fetchOptions, headers }); if (response.status === 401 && retryOnUnauthorized && retryCount < maxRetries) { const newToken = await authManager.getIdToken(true); headers['Authorization'] = `Bearer ${newToken}`; retryCount++; continue; } return response; } catch (error) { lastError = error; retryCount++; if (retryCount > maxRetries) { break; } } } throw lastError || new Error('Fetch failed'); } async function authenticatedJSON(url, options = {}) { const response = await authenticatedFetch(url, { ...options, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', ...options.headers } }); if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP ${response.status}: ${errorText}`); } return response.json(); } async function authenticatedPost(url, data, options = {}) { return authenticatedJSON(url, { ...options, method: 'POST', body: JSON.stringify(data) }); } async function authenticatedGet(url, options = {}) { return authenticatedJSON(url, { ...options, method: 'GET' }); } async function authenticatedDelete(url, options = {}) { return authenticatedJSON(url, { ...options, method: 'DELETE' }); } async function authenticatedPut(url, data, options = {}) { return authenticatedJSON(url, { ...options, method: 'PUT', body: JSON.stringify(data) }); } async function authenticatedPatch(url, data, options = {}) { return authenticatedJSON(url, { ...options, method: 'PATCH', body: JSON.stringify(data) }); } async function authenticatedUpload(url, file, options = {}) { const formData = new FormData(); formData.append(options.fieldName || 'file', file); if (options.body && typeof options.body === 'object') { Object.entries(options.body).forEach(([key, value]) => { if (key !== options.fieldName) { formData.append(key, String(value)); } }); } return authenticatedFetch(url, { ...options, method: 'POST', body: formData, headers: { ...options.headers } }); } function createAuthenticatedClient(baseURL) { const resolveURL = (path) => { if (path.startsWith('http')) return path; return `${baseURL.replace(/\/$/, '')}/${path.replace(/^\//, '')}`; }; return { fetch: (path, options) => authenticatedFetch(resolveURL(path), options), get: (path, options) => authenticatedGet(resolveURL(path), options), post: (path, data, options) => authenticatedPost(resolveURL(path), data, options), put: (path, data, options) => authenticatedPut(resolveURL(path), data, options), patch: (path, data, options) => authenticatedPatch(resolveURL(path), data, options), delete: (path, options) => authenticatedDelete(resolveURL(path), options), upload: (path, file, options) => authenticatedUpload(resolveURL(path), file, options) }; }