mirror of
https://github.com/AeThex-Corporation/AeThex-OS.git
synced 2026-04-18 14:27:20 +00:00
Integrate Supabase Auth for user login and sign-up, replacing the previous custom authentication system. This change modifies API routes, frontend authentication context, and the login page to support email-based authentication and a new sign-up flow. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 279f1558-c0e3-40e4-8217-be7e9f4c6eca Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: 7b6bc38e-d7e0-4263-881e-db7e4f1e15bb Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/b984cb14-1d19-4944-922b-bc79e821ed35/279f1558-c0e3-40e4-8217-be7e9f4c6eca/bgcvGPx Replit-Helium-Checkpoint-Created: true
231 lines
5.8 KiB
TypeScript
231 lines
5.8 KiB
TypeScript
import { type Profile, type Project } from "@shared/schema";
|
|
import { supabase } from "./supabase";
|
|
|
|
export interface IStorage {
|
|
// Profiles
|
|
getProfiles(): Promise<Profile[]>;
|
|
getProfile(id: string): Promise<Profile | undefined>;
|
|
getProfileByUsername(username: string): Promise<Profile | undefined>;
|
|
updateProfile(id: string, data: Partial<Profile>): Promise<Profile | undefined>;
|
|
|
|
// Projects
|
|
getProjects(): Promise<Project[]>;
|
|
getProject(id: string): Promise<Project | undefined>;
|
|
|
|
// Sites
|
|
getSites(): Promise<any[]>;
|
|
|
|
// Auth Logs
|
|
getAuthLogs(): Promise<any[]>;
|
|
|
|
// Achievements
|
|
getAchievements(): Promise<any[]>;
|
|
|
|
// Applications
|
|
getApplications(): Promise<any[]>;
|
|
updateApplication(id: string, updates: any): Promise<any>;
|
|
|
|
// Alerts
|
|
getAlerts(): Promise<any[]>;
|
|
updateAlert(id: string, updates: any): Promise<any>;
|
|
|
|
// Metrics
|
|
getMetrics(): Promise<{
|
|
totalProfiles: number;
|
|
totalProjects: number;
|
|
onlineUsers: number;
|
|
verifiedUsers: number;
|
|
totalXP: number;
|
|
avgLevel: number;
|
|
}>;
|
|
}
|
|
|
|
export class SupabaseStorage implements IStorage {
|
|
|
|
async getProfiles(): Promise<Profile[]> {
|
|
const { data, error } = await supabase
|
|
.from('profiles')
|
|
.select('*')
|
|
.order('created_at', { ascending: false });
|
|
|
|
if (error) return [];
|
|
return data as Profile[];
|
|
}
|
|
|
|
async getProfile(id: string): Promise<Profile | undefined> {
|
|
const { data, error } = await supabase
|
|
.from('profiles')
|
|
.select('*')
|
|
.eq('id', id)
|
|
.single();
|
|
|
|
if (error || !data) return undefined;
|
|
return data as Profile;
|
|
}
|
|
|
|
async getProfileByUsername(username: string): Promise<Profile | undefined> {
|
|
const { data, error } = await supabase
|
|
.from('profiles')
|
|
.select('*')
|
|
.eq('username', username)
|
|
.single();
|
|
|
|
if (error || !data) return undefined;
|
|
return data as Profile;
|
|
}
|
|
|
|
async updateProfile(id: string, updates: Partial<Profile>): Promise<Profile | undefined> {
|
|
const { data, error } = await supabase
|
|
.from('profiles')
|
|
.update({ ...updates, updated_at: new Date().toISOString() })
|
|
.eq('id', id)
|
|
.select()
|
|
.single();
|
|
|
|
if (error || !data) return undefined;
|
|
return data as Profile;
|
|
}
|
|
|
|
async getProjects(): Promise<Project[]> {
|
|
const { data, error } = await supabase
|
|
.from('projects')
|
|
.select('*')
|
|
.order('created_at', { ascending: false });
|
|
|
|
if (error) return [];
|
|
return data as Project[];
|
|
}
|
|
|
|
async getProject(id: string): Promise<Project | undefined> {
|
|
const { data, error } = await supabase
|
|
.from('projects')
|
|
.select('*')
|
|
.eq('id', id)
|
|
.single();
|
|
|
|
if (error || !data) return undefined;
|
|
return data as Project;
|
|
}
|
|
|
|
async getSites(): Promise<any[]> {
|
|
const { data, error } = await supabase
|
|
.from('aethex_sites')
|
|
.select('*')
|
|
.order('last_check', { ascending: false });
|
|
|
|
if (error) return [];
|
|
return data || [];
|
|
}
|
|
|
|
async getAuthLogs(): Promise<any[]> {
|
|
const { data, error } = await supabase
|
|
.from('auth_logs')
|
|
.select('*')
|
|
.order('created_at', { ascending: false })
|
|
.limit(100);
|
|
|
|
if (error) return [];
|
|
return data || [];
|
|
}
|
|
|
|
async getAchievements(): Promise<any[]> {
|
|
const { data, error } = await supabase
|
|
.from('achievements')
|
|
.select('*')
|
|
.order('name', { ascending: true });
|
|
|
|
if (error) return [];
|
|
return data || [];
|
|
}
|
|
|
|
async getApplications(): Promise<any[]> {
|
|
const { data, error } = await supabase
|
|
.from('applications')
|
|
.select('*')
|
|
.order('submitted_at', { ascending: false });
|
|
|
|
if (error) return [];
|
|
return data || [];
|
|
}
|
|
|
|
async getAlerts(): Promise<any[]> {
|
|
const { data, error } = await supabase
|
|
.from('aethex_alerts')
|
|
.select('*')
|
|
.order('created_at', { ascending: false })
|
|
.limit(50);
|
|
|
|
if (error) return [];
|
|
return data || [];
|
|
}
|
|
|
|
async updateAlert(id: string, updates: any): Promise<any> {
|
|
const updateData: any = {};
|
|
if ('is_resolved' in updates) {
|
|
updateData.is_resolved = updates.is_resolved;
|
|
}
|
|
|
|
const { data, error } = await supabase
|
|
.from('aethex_alerts')
|
|
.update(updateData)
|
|
.eq('id', id)
|
|
.select()
|
|
.single();
|
|
|
|
if (error) {
|
|
console.error('Update alert error:', error);
|
|
throw new Error(error.message);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
async updateApplication(id: string, updates: any): Promise<any> {
|
|
const updateData: any = {};
|
|
if ('status' in updates) {
|
|
updateData.status = updates.status;
|
|
}
|
|
|
|
const { data, error } = await supabase
|
|
.from('applications')
|
|
.update(updateData)
|
|
.eq('id', id)
|
|
.select()
|
|
.single();
|
|
|
|
if (error) {
|
|
console.error('Update application error:', error);
|
|
throw new Error(error.message);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
async getMetrics(): Promise<{
|
|
totalProfiles: number;
|
|
totalProjects: number;
|
|
onlineUsers: number;
|
|
verifiedUsers: number;
|
|
totalXP: number;
|
|
avgLevel: number;
|
|
}> {
|
|
const profiles = await this.getProfiles();
|
|
const projects = await this.getProjects();
|
|
|
|
const onlineUsers = profiles.filter(p => p.status === 'online').length;
|
|
const verifiedUsers = profiles.filter(p => p.is_verified).length;
|
|
const totalXP = profiles.reduce((sum, p) => sum + (p.total_xp || 0), 0);
|
|
const avgLevel = profiles.length > 0
|
|
? profiles.reduce((sum, p) => sum + (p.level || 1), 0) / profiles.length
|
|
: 1;
|
|
|
|
return {
|
|
totalProfiles: profiles.length,
|
|
totalProjects: projects.length,
|
|
onlineUsers,
|
|
verifiedUsers,
|
|
totalXP,
|
|
avgLevel: Math.round(avgLevel * 10) / 10,
|
|
};
|
|
}
|
|
}
|
|
|
|
export const storage = new SupabaseStorage();
|