feat: initial public release

ConsentOS — a privacy-first cookie consent management platform.

Self-hosted, source-available alternative to OneTrust, Cookiebot, and
CookieYes. Full standards coverage (IAB TCF v2.2, GPP v1, Google
Consent Mode v2, GPC, Shopify Customer Privacy API), multi-tenant
architecture with role-based access, configuration cascade
(system → org → group → site → region), dark-pattern detection in
the scanner, and a tamper-evident consent record audit trail.

This is the initial public release. Prior development history is
retained internally.

See README.md for the feature list, architecture overview, and
quick-start instructions. Licensed under the Elastic Licence 2.0 —
self-host freely; do not resell as a managed service.
This commit is contained in:
James Cottrill
2026-04-13 14:20:15 +00:00
commit fbf26453f2
341 changed files with 62807 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
import { create } from 'zustand';
import { getMe, login as loginApi } from '../api/auth';
import { initAnalytics, trackAuthEvent } from '../services/analytics';
import type { User } from '../types/api';
interface AuthState {
user: User | null;
isAuthenticated: boolean;
isLoading: boolean;
login: (email: string, password: string) => Promise<void>;
logout: () => void;
loadUser: () => Promise<void>;
}
export const useAuthStore = create<AuthState>((set) => ({
user: null,
isAuthenticated: !!localStorage.getItem('access_token'),
isLoading: false,
login: async (email: string, password: string) => {
set({ isLoading: true });
try {
const tokens = await loginApi(email, password);
localStorage.setItem('access_token', tokens.access_token);
localStorage.setItem('refresh_token', tokens.refresh_token);
const user = await getMe();
set({ user, isAuthenticated: true, isLoading: false });
initAnalytics(user);
trackAuthEvent('login', user.id);
} catch (error) {
set({ isLoading: false });
throw error;
}
},
logout: () => {
const { user } = useAuthStore.getState();
trackAuthEvent('logout', user?.id);
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
set({ user: null, isAuthenticated: false });
},
loadUser: async () => {
if (!localStorage.getItem('access_token')) {
set({ isAuthenticated: false });
return;
}
set({ isLoading: true });
try {
const user = await getMe();
set({ user, isAuthenticated: true, isLoading: false });
initAnalytics(user);
} catch {
localStorage.removeItem('access_token');
set({ user: null, isAuthenticated: false, isLoading: false });
}
},
}));