Files
thetool/public/mobile/shared/auth.js
2026-01-13 12:44:45 +01:00

200 lines
5.5 KiB
JavaScript

/**
* MobileApp Shared Authentication Module
*
* Provides authentication utilities for all mobile PWAs:
* - checkAuth() - Check if user is authenticated
* - login() - Authenticate user
* - logout() - Clear session
* - api - Generic API helper
*/
// Base API path for all MobileApp endpoints
const API_BASE = '/MobileApp';
// Shared auth state (can be imported by components)
export const authState = {
user: null,
isAuthenticated: false
};
/**
* Check if user is currently authenticated
* @returns {Promise<{authenticated: boolean, user?: object}>}
*/
export async function checkAuth() {
try {
const res = await fetch(`${API_BASE}/auth/check`, {
credentials: 'same-origin'
});
const data = await res.json();
authState.isAuthenticated = data.authenticated;
authState.user = data.user || null;
return data;
} catch (e) {
console.error('Auth check failed:', e);
authState.isAuthenticated = false;
authState.user = null;
return { authenticated: false };
}
}
/**
* Authenticate user with credentials
* @param {object} credentials - { username, password, rememberMe }
* @returns {Promise<{success: boolean, user?: object, message?: string}>}
*/
export async function login({ username, password, rememberMe = true }) {
try {
const res = await fetch(`${API_BASE}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'same-origin',
body: JSON.stringify({ username, password, rememberMe })
});
const data = await res.json();
if (data.success) {
authState.isAuthenticated = true;
authState.user = data.user;
}
return data;
} catch (e) {
console.error('Login failed:', e);
return { success: false, message: 'Netzwerkfehler' };
}
}
/**
* Verify 2FA code
* @param {string} code - 5-digit verification code
* @returns {Promise<{success: boolean, user?: object, message?: string}>}
*/
export async function verify2FA(code) {
try {
const res = await fetch(`${API_BASE}/auth/verify2fa`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'same-origin',
body: JSON.stringify({ code })
});
const data = await res.json();
if (data.success) {
authState.isAuthenticated = true;
authState.user = data.user;
}
return data;
} catch (e) {
console.error('2FA verification failed:', e);
return { success: false, message: 'Netzwerkfehler' };
}
}
/**
* Resend 2FA code
* @returns {Promise<{success: boolean, message?: string}>}
*/
export async function resend2FA() {
try {
const res = await fetch(`${API_BASE}/auth/resend2fa`, {
method: 'POST',
credentials: 'same-origin'
});
return await res.json();
} catch (e) {
console.error('Resend 2FA failed:', e);
return { success: false, message: 'Netzwerkfehler' };
}
}
/**
* Logout current user
* @returns {Promise<{success: boolean}>}
*/
export async function logout() {
try {
await fetch(`${API_BASE}/auth/logout`, {
method: 'POST',
credentials: 'same-origin'
});
} catch (e) {
console.error('Logout request failed:', e);
}
authState.isAuthenticated = false;
authState.user = null;
return { success: true };
}
/**
* Generic API helper for app-specific endpoints
* Usage: api.get('WarehouseStocktake/getActiveStocktakes')
* api.post('WarehouseStocktake/submitScan', { ... })
*/
export const api = {
/**
* GET request
* @param {string} endpoint - Endpoint path (e.g., 'WarehouseStocktake/getArticle?code=123')
* @returns {Promise<object>}
*/
get: async (endpoint) => {
try {
const res = await fetch(`${API_BASE}/${endpoint}`, {
credentials: 'same-origin'
});
// Check for auth errors
if (res.status === 401) {
authState.isAuthenticated = false;
authState.user = null;
return { success: false, error: 'Not authenticated', authError: true };
}
return await res.json();
} catch (e) {
console.error(`API GET ${endpoint} failed:`, e);
return { success: false, error: 'Netzwerkfehler' };
}
},
/**
* POST request with JSON body
* @param {string} endpoint - Endpoint path
* @param {object} data - Request body
* @returns {Promise<object>}
*/
post: async (endpoint, data = {}) => {
try {
const res = await fetch(`${API_BASE}/${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'same-origin',
body: JSON.stringify(data)
});
// Check for auth errors
if (res.status === 401) {
authState.isAuthenticated = false;
authState.user = null;
return { success: false, error: 'Not authenticated', authError: true };
}
return await res.json();
} catch (e) {
console.error(`API POST ${endpoint} failed:`, e);
return { success: false, error: 'Netzwerkfehler' };
}
}
};
// Export API_BASE for components that need to build URLs
export { API_BASE };