mobile download
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
import { storageGetSync, storageRemove, storageSetSync } from './storage/index.js';
|
||||
|
||||
export type UserRole = 'ADMIN' | 'USER';
|
||||
|
||||
export interface AuthSession {
|
||||
userId: number;
|
||||
username: string;
|
||||
displayName: string;
|
||||
role: UserRole;
|
||||
}
|
||||
|
||||
const USER_ID_KEY = 'gc_user_id';
|
||||
const USERNAME_KEY = 'gc_username';
|
||||
const DISPLAY_NAME_KEY = 'gc_display_name';
|
||||
const ROLE_KEY = 'gc_user_role';
|
||||
|
||||
function normalizeRole(role: string): UserRole {
|
||||
return role === 'ADMIN' ? 'ADMIN' : 'USER';
|
||||
}
|
||||
|
||||
export function getAuthSession(): AuthSession | null {
|
||||
const id = storageGetSync(USER_ID_KEY);
|
||||
if (!id) return null;
|
||||
const userId = Number(id);
|
||||
if (!Number.isFinite(userId) || userId <= 0) return null;
|
||||
const username = storageGetSync(USERNAME_KEY) ?? '';
|
||||
const displayName = storageGetSync(DISPLAY_NAME_KEY) ?? username;
|
||||
const storedRole = storageGetSync(ROLE_KEY);
|
||||
const role = normalizeRole(storedRole ?? 'USER');
|
||||
return { userId, username, displayName, role };
|
||||
}
|
||||
|
||||
export function setAuthSession(session: AuthSession): void {
|
||||
storageSetSync(USER_ID_KEY, String(session.userId));
|
||||
storageSetSync(USERNAME_KEY, session.username);
|
||||
storageSetSync(DISPLAY_NAME_KEY, session.displayName);
|
||||
storageSetSync(ROLE_KEY, session.role);
|
||||
}
|
||||
|
||||
export async function clearAuthSession(): Promise<void> {
|
||||
await storageRemove(USER_ID_KEY);
|
||||
await storageRemove(USERNAME_KEY);
|
||||
await storageRemove(DISPLAY_NAME_KEY);
|
||||
await storageRemove(ROLE_KEY);
|
||||
}
|
||||
|
||||
export function isLoggedIn(): boolean {
|
||||
return getAuthSession() !== null;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export * from './api/backendApi';
|
||||
export {
|
||||
initStorage,
|
||||
storageGet,
|
||||
storageSet,
|
||||
storageGetSync,
|
||||
storageSetSync,
|
||||
storageRemove,
|
||||
} from './storage/index';
|
||||
export * from './auth';
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Storage adapter — Capacitor Preferences (native) with localStorage fallback (browser dev).
|
||||
*/
|
||||
import { Preferences } from '@capacitor/preferences';
|
||||
|
||||
const memoryCache = new Map<string, string>();
|
||||
let prefsReady = false;
|
||||
|
||||
async function ensurePrefs(): Promise<boolean> {
|
||||
if (prefsReady) return true;
|
||||
try {
|
||||
await Preferences.get({ key: '__probe__' });
|
||||
prefsReady = true;
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function storageGet(key: string): Promise<string | null> {
|
||||
if (memoryCache.has(key)) return memoryCache.get(key) ?? null;
|
||||
if (await ensurePrefs()) {
|
||||
const { value } = await Preferences.get({ key });
|
||||
if (value != null) {
|
||||
memoryCache.set(key, value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
return localStorage.getItem(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function storageSet(key: string, value: string): Promise<void> {
|
||||
memoryCache.set(key, value);
|
||||
if (await ensurePrefs()) {
|
||||
await Preferences.set({ key, value });
|
||||
}
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
export async function storageRemove(key: string): Promise<void> {
|
||||
memoryCache.delete(key);
|
||||
if (await ensurePrefs()) {
|
||||
await Preferences.remove({ key });
|
||||
}
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
|
||||
/** Sync read for hot paths (uses memory cache populated at init). */
|
||||
export function storageGetSync(key: string): string | null {
|
||||
if (memoryCache.has(key)) return memoryCache.get(key) ?? null;
|
||||
if (typeof localStorage !== 'undefined') return localStorage.getItem(key);
|
||||
return null;
|
||||
}
|
||||
|
||||
export function storageSetSync(key: string, value: string): void {
|
||||
memoryCache.set(key, value);
|
||||
if (typeof localStorage !== 'undefined') localStorage.setItem(key, value);
|
||||
void storageSet(key, value);
|
||||
}
|
||||
|
||||
export async function initStorage(): Promise<void> {
|
||||
const keys = ['gc_device_id', 'gc_user_id', 'gc_username', 'gc_display_name', 'gc_user_role', 'gc_api_base_url'];
|
||||
if (!(await ensurePrefs())) return;
|
||||
for (const key of keys) {
|
||||
const { value } = await Preferences.get({ key });
|
||||
if (value != null) memoryCache.set(key, value);
|
||||
}
|
||||
}
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_API_BASE_URL?: string;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
||||
Reference in New Issue
Block a user