@tradly/auth
Version:
Auth package for Tradly - handles authentication (email, phone, social login)
275 lines (274 loc) • 11 kB
JavaScript
;
/**
* Fetch utility for Auth package
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.apiFetch = apiFetch;
exports.get = get;
exports.post = post;
exports.put = put;
exports.del = del;
const config_1 = require("./config");
const authKey_1 = require("./authKey");
const cache_1 = require("./cache");
const pkKey_1 = require("../services/pkKey");
/**
* Make API request
*/
async function apiFetch(url, options = {}) {
const { currency, language, pkKey: providedPkKey = "", authKey: providedAuthKey = "", headers = {}, checkAuth = true, ...fetchOptions } = options;
// Always use baseUrl from global config (from initializeAuth)
const baseUrl = (0, config_1.getBaseUrl)();
if (!baseUrl) {
throw new Error("BaseUrl is required. Please call initializeAuth first.");
}
const fullUrl = `${baseUrl}${url}`;
// Automatically get auth key or PK key if checkAuth is true
let authKey = providedAuthKey;
let pkKey = providedPkKey;
if (checkAuth && !pkKey && !authKey) {
// First try to get auth key (for user authentication)
const retrievedAuthKey = (0, authKey_1.getAuthKey)();
if (retrievedAuthKey) {
authKey = retrievedAuthKey;
pkKey = (0, pkKey_1.getCachedPKKey)((0, config_1.getDomain)(), (0, config_1.getEnv)() || "production")?.key;
}
// If no auth key, try to get PK key from domain
if (!authKey) {
const domain = (0, config_1.getDomain)();
const env = (0, config_1.getEnv)() || "production";
if (domain) {
// Try to get cached PK key first (check cache directly to avoid circular dependency)
const cacheKey = `pk_key_${domain}_${env}`;
const cookieName = `${domain}_pk_key_${env}`;
const cachedPkKey = cache_1.cache.get(cacheKey);
if (cachedPkKey?.key) {
pkKey = cachedPkKey.key;
}
else {
// Check encrypted cookie (browser only)
if (typeof window !== "undefined" &&
typeof document !== "undefined") {
const cookies = document.cookie.split(";");
for (let cookie of cookies) {
const [key, value] = cookie
.trim()
.split("=");
if (key === cookieName &&
value) {
try {
// Lazy import to avoid circular dependency
const { decryptPKKey, } = await Promise.resolve().then(() => __importStar(require("../utils/encryption")));
const decryptedKey = decryptPKKey(decodeURIComponent(value), domain);
if (decryptedKey) {
pkKey =
decryptedKey;
// Cache it
cache_1.cache.set(cacheKey, {
key: decryptedKey,
domain: {
id: 0,
},
}, 3600000);
break;
}
}
catch (e) {
console.warn("Failed to decrypt PK key from cookie:", e);
}
}
}
}
// If still not found, fetch it directly (avoiding circular dependency)
if (!pkKey) {
try {
const pkKeyUrl = `${baseUrl}/skua/tenants/pk_by_domain?domain=${domain}&env=${env}`;
const pkResponse = await fetch(pkKeyUrl, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
if (pkResponse.ok) {
const pkData = await pkResponse.json();
const pkKeyData = (pkData.data
?.data ||
pkData.data ||
pkData);
if (pkKeyData?.key) {
pkKey =
pkKeyData.key;
// Cache it for future use
cache_1.cache.set(cacheKey, pkKeyData, 3600000); // 1 hour
// Store encrypted in cookie (browser only)
if (typeof window !==
"undefined" &&
typeof document !==
"undefined") {
try {
const { encryptPKKey, } = await Promise.resolve().then(() => __importStar(require("../utils/encryption")));
const encryptedKey = encryptPKKey(pkKey, domain);
const maxAge = 3600; // 1 hour in seconds
document.cookie = `${cookieName}=${encodeURIComponent(encryptedKey)}; max-age=${maxAge}; path=/; SameSite=Lax`;
}
catch (e) {
console.warn("Failed to store PK key in cookie:", e);
}
}
}
}
}
catch (error) {
console.warn("Failed to fetch PK key:", error);
}
}
}
}
// If still no key, throw error
if (!pkKey) {
throw new Error("PK key or auth key is required. Either provide it, call initializeAuth first, or ensure auth key is set.");
}
}
}
// Extract headers from original options if present in RequestInit
const originalHeaders = options.headers;
let fetchHeaders = {};
if (originalHeaders && originalHeaders !== headers) {
if (originalHeaders instanceof Headers) {
originalHeaders.forEach((value, key) => {
fetchHeaders[key] = value;
});
}
else if (Array.isArray(originalHeaders)) {
fetchHeaders = Object.fromEntries(originalHeaders);
}
else {
fetchHeaders = originalHeaders;
}
}
const requestHeaders = {
"Content-Type": "application/json",
...fetchHeaders,
...headers,
};
// Add PK key as Bearer token (for tenant identification)
// PK key takes precedence for tenant-level APIs
if (pkKey) {
requestHeaders["Authorization"] = `Bearer ${pkKey}`;
}
// Add auth key as Bearer token (for user authentication)
// Auth key is used for authenticated user APIs
// If both are provided, auth key overrides PK key
if (authKey) {
requestHeaders["x-auth-key"] = `${authKey}`;
}
// Add language header if provided
if (language) {
requestHeaders["X-language"] = language;
}
// Add currency header if provided
if (currency) {
requestHeaders["X-currency"] = currency;
}
try {
const response = await fetch(fullUrl, {
...fetchOptions,
headers: requestHeaders,
});
const data = await response.json();
const result = {
status: response.ok && data.status !== false,
data: data.data || data,
error: !response.ok || data.status === false
? {
code: data.code ||
response.status,
message: data.message ||
response.statusText,
}
: undefined,
};
return result;
}
catch (error) {
return {
status: false,
data: null,
error: {
code: 500,
message: error.message || "Network error",
},
};
}
}
/**
* GET request
*/
async function get(url, options = {}) {
return apiFetch(url, {
...options,
method: "GET",
});
}
/**
* POST request
*/
async function post(url, body, options = {}) {
return apiFetch(url, {
...options,
method: "POST",
body: body ? JSON.stringify(body) : undefined,
});
}
/**
* PUT request
*/
async function put(url, body, options = {}) {
return apiFetch(url, {
...options,
method: "PUT",
body: body ? JSON.stringify(body) : undefined,
});
}
/**
* DELETE request
*/
async function del(url, options = {}) {
return apiFetch(url, {
...options,
method: "DELETE",
});
}