mirror of
https://github.com/domfelipe/mika-agent-assist.git
synced 2026-08-07 09:16:46 +00:00
Changes
Co-authored-by: domfelipe <53182096+domfelipe@users.noreply.github.com>
This commit is contained in:
parent
c0203dea0c
commit
6184835992
8 changed files with 312 additions and 0 deletions
5
.env
Normal file
5
.env
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
SUPABASE_PUBLISHABLE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InNtc2FybWdvaXJsY2VkbXF2ZGdjIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzY0MzczNjAsImV4cCI6MjA5MjAxMzM2MH0.AjMSQOn3BtzV-fJ2x9SWoM2ozjLyPD6g3dmTSeCT9II"
|
||||||
|
SUPABASE_URL="https://smsarmgoirlcedmqvdgc.supabase.co"
|
||||||
|
VITE_SUPABASE_PROJECT_ID="smsarmgoirlcedmqvdgc"
|
||||||
|
VITE_SUPABASE_PUBLISHABLE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InNtc2FybWdvaXJsY2VkbXF2ZGdjIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzY0MzczNjAsImV4cCI6MjA5MjAxMzM2MH0.AjMSQOn3BtzV-fJ2x9SWoM2ozjLyPD6g3dmTSeCT9II"
|
||||||
|
VITE_SUPABASE_URL="https://smsarmgoirlcedmqvdgc.supabase.co"
|
||||||
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
|
@ -40,6 +40,7 @@
|
||||||
"@radix-ui/react-toggle": "^1.1.10",
|
"@radix-ui/react-toggle": "^1.1.10",
|
||||||
"@radix-ui/react-toggle-group": "^1.1.11",
|
"@radix-ui/react-toggle-group": "^1.1.11",
|
||||||
"@radix-ui/react-tooltip": "^1.2.8",
|
"@radix-ui/react-tooltip": "^1.2.8",
|
||||||
|
"@supabase/supabase-js": "^2.103.3",
|
||||||
"@tailwindcss/vite": "^4.2.1",
|
"@tailwindcss/vite": "^4.2.1",
|
||||||
"@tanstack/react-query": "^5.99.0",
|
"@tanstack/react-query": "^5.99.0",
|
||||||
"@tanstack/react-router": "^1.168.0",
|
"@tanstack/react-router": "^1.168.0",
|
||||||
|
|
|
||||||
77
src/integrations/supabase/auth-middleware.ts
Normal file
77
src/integrations/supabase/auth-middleware.ts
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
// This file is automatically generated. Do not edit it directly.
|
||||||
|
import { createMiddleware } from '@tanstack/react-start'
|
||||||
|
import { getRequest } from '@tanstack/react-start/server'
|
||||||
|
import { createClient } from '@supabase/supabase-js'
|
||||||
|
import type { Database } from './types'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const requireSupabaseAuth = createMiddleware({ type: 'function' }).server(
|
||||||
|
async ({ next }) => {
|
||||||
|
|
||||||
|
const SUPABASE_URL = process.env.SUPABASE_URL;
|
||||||
|
const SUPABASE_PUBLISHABLE_KEY = process.env.SUPABASE_PUBLISHABLE_KEY;
|
||||||
|
|
||||||
|
if (!SUPABASE_URL || !SUPABASE_PUBLISHABLE_KEY) {
|
||||||
|
throw new Response(
|
||||||
|
'Missing Supabase environment variables. Ensure SUPABASE_URL and SUPABASE_PUBLISHABLE_KEY are set.',
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const request = getRequest();
|
||||||
|
|
||||||
|
if (!request?.headers) {
|
||||||
|
throw new Response('Unauthorized: No request headers available', { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const authHeader = request.headers.get('authorization');
|
||||||
|
|
||||||
|
if (!authHeader) {
|
||||||
|
throw new Response('Unauthorized: No authorization header provided', { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!authHeader.startsWith('Bearer ')) {
|
||||||
|
throw new Response('Unauthorized: Only Bearer tokens are supported', { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = authHeader.replace('Bearer ', '');
|
||||||
|
if (!token) {
|
||||||
|
throw new Response('Unauthorized: No token provided', { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const supabase = createClient<Database>(
|
||||||
|
SUPABASE_URL!,
|
||||||
|
SUPABASE_PUBLISHABLE_KEY!,
|
||||||
|
{
|
||||||
|
global: {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
auth: {
|
||||||
|
storage: undefined,
|
||||||
|
persistSession: false,
|
||||||
|
autoRefreshToken: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const { data, error } = await supabase.auth.getClaims(token);
|
||||||
|
if (error || !data?.claims) {
|
||||||
|
throw new Response('Unauthorized: Invalid token', { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.claims.sub) {
|
||||||
|
throw new Response('Unauthorized: No user ID found in token', { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return next({
|
||||||
|
context: {
|
||||||
|
supabase,
|
||||||
|
userId: data.claims.sub,
|
||||||
|
claims: data.claims,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
37
src/integrations/supabase/client.server.ts
Normal file
37
src/integrations/supabase/client.server.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
// This file is automatically generated. Do not edit it directly.
|
||||||
|
// Server-side Supabase client with service role key - bypasses RLS.
|
||||||
|
// Use this for admin operations in server functions and server routes only.
|
||||||
|
// For user-authenticated queries (with RLS), use the auth middleware instead.
|
||||||
|
import { createClient } from '@supabase/supabase-js';
|
||||||
|
import type { Database } from './types';
|
||||||
|
|
||||||
|
function createSupabaseAdminClient() {
|
||||||
|
const SUPABASE_URL = process.env.SUPABASE_URL;
|
||||||
|
const SUPABASE_SERVICE_ROLE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
||||||
|
|
||||||
|
if (!SUPABASE_URL || !SUPABASE_SERVICE_ROLE_KEY) {
|
||||||
|
throw new Error(
|
||||||
|
'Missing Supabase server environment variables. Ensure SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY are set.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return createClient<Database>(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, {
|
||||||
|
auth: {
|
||||||
|
storage: undefined,
|
||||||
|
persistSession: false,
|
||||||
|
autoRefreshToken: false,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let _supabaseAdmin: ReturnType<typeof createSupabaseAdminClient> | undefined;
|
||||||
|
|
||||||
|
// Server-side Supabase client with service role - bypasses RLS
|
||||||
|
// SECURITY: Only use this for trusted server-side operations, never expose to client code
|
||||||
|
// Import like: import { supabaseAdmin } from "@/integrations/supabase/client.server";
|
||||||
|
export const supabaseAdmin = new Proxy({} as ReturnType<typeof createSupabaseAdminClient>, {
|
||||||
|
get(_, prop, receiver) {
|
||||||
|
if (!_supabaseAdmin) _supabaseAdmin = createSupabaseAdminClient();
|
||||||
|
return Reflect.get(_supabaseAdmin, prop, receiver);
|
||||||
|
},
|
||||||
|
});
|
||||||
36
src/integrations/supabase/client.ts
Normal file
36
src/integrations/supabase/client.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
// This file is automatically generated. Do not edit it directly.
|
||||||
|
import { createClient } from '@supabase/supabase-js';
|
||||||
|
import type { Database } from './types';
|
||||||
|
|
||||||
|
function createSupabaseClient() {
|
||||||
|
// Use import.meta.env for client-side (Vite build-time replacement)
|
||||||
|
// Fall back to process.env for SSR (server-side rendering)
|
||||||
|
const SUPABASE_URL = import.meta.env.VITE_SUPABASE_URL || process.env.SUPABASE_URL;
|
||||||
|
const SUPABASE_PUBLISHABLE_KEY = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY || process.env.SUPABASE_PUBLISHABLE_KEY;
|
||||||
|
|
||||||
|
if (!SUPABASE_URL || !SUPABASE_PUBLISHABLE_KEY) {
|
||||||
|
throw new Error(
|
||||||
|
'Missing Supabase environment variables. Ensure SUPABASE_URL and SUPABASE_PUBLISHABLE_KEY (or VITE_ prefixed versions) are set in your .env file.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return createClient<Database>(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, {
|
||||||
|
auth: {
|
||||||
|
storage: typeof window !== 'undefined' ? localStorage : undefined,
|
||||||
|
persistSession: true,
|
||||||
|
autoRefreshToken: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let _supabase: ReturnType<typeof createSupabaseClient> | undefined;
|
||||||
|
|
||||||
|
// Import the supabase client like this:
|
||||||
|
// import { supabase } from "@/integrations/supabase/client";
|
||||||
|
export const supabase = new Proxy({} as ReturnType<typeof createSupabaseClient>, {
|
||||||
|
get(_, prop, receiver) {
|
||||||
|
if (!_supabase) _supabase = createSupabaseClient();
|
||||||
|
return Reflect.get(_supabase, prop, receiver);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
155
src/integrations/supabase/types.ts
Normal file
155
src/integrations/supabase/types.ts
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
export type Json =
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| null
|
||||||
|
| { [key: string]: Json | undefined }
|
||||||
|
| Json[]
|
||||||
|
|
||||||
|
export type Database = {
|
||||||
|
// Allows to automatically instantiate createClient with right options
|
||||||
|
// instead of createClient<Database, { PostgrestVersion: 'XX' }>(URL, KEY)
|
||||||
|
__InternalSupabase: {
|
||||||
|
PostgrestVersion: "14.5"
|
||||||
|
}
|
||||||
|
public: {
|
||||||
|
Tables: {
|
||||||
|
[_ in never]: never
|
||||||
|
}
|
||||||
|
Views: {
|
||||||
|
[_ in never]: never
|
||||||
|
}
|
||||||
|
Functions: {
|
||||||
|
[_ in never]: never
|
||||||
|
}
|
||||||
|
Enums: {
|
||||||
|
[_ in never]: never
|
||||||
|
}
|
||||||
|
CompositeTypes: {
|
||||||
|
[_ in never]: never
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DatabaseWithoutInternals = Omit<Database, "__InternalSupabase">
|
||||||
|
|
||||||
|
type DefaultSchema = DatabaseWithoutInternals[Extract<keyof Database, "public">]
|
||||||
|
|
||||||
|
export type Tables<
|
||||||
|
DefaultSchemaTableNameOrOptions extends
|
||||||
|
| keyof (DefaultSchema["Tables"] & DefaultSchema["Views"])
|
||||||
|
| { schema: keyof DatabaseWithoutInternals },
|
||||||
|
TableName extends DefaultSchemaTableNameOrOptions extends {
|
||||||
|
schema: keyof DatabaseWithoutInternals
|
||||||
|
}
|
||||||
|
? keyof (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] &
|
||||||
|
DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"])
|
||||||
|
: never = never,
|
||||||
|
> = DefaultSchemaTableNameOrOptions extends {
|
||||||
|
schema: keyof DatabaseWithoutInternals
|
||||||
|
}
|
||||||
|
? (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] &
|
||||||
|
DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"])[TableName] extends {
|
||||||
|
Row: infer R
|
||||||
|
}
|
||||||
|
? R
|
||||||
|
: never
|
||||||
|
: DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema["Tables"] &
|
||||||
|
DefaultSchema["Views"])
|
||||||
|
? (DefaultSchema["Tables"] &
|
||||||
|
DefaultSchema["Views"])[DefaultSchemaTableNameOrOptions] extends {
|
||||||
|
Row: infer R
|
||||||
|
}
|
||||||
|
? R
|
||||||
|
: never
|
||||||
|
: never
|
||||||
|
|
||||||
|
export type TablesInsert<
|
||||||
|
DefaultSchemaTableNameOrOptions extends
|
||||||
|
| keyof DefaultSchema["Tables"]
|
||||||
|
| { schema: keyof DatabaseWithoutInternals },
|
||||||
|
TableName extends DefaultSchemaTableNameOrOptions extends {
|
||||||
|
schema: keyof DatabaseWithoutInternals
|
||||||
|
}
|
||||||
|
? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"]
|
||||||
|
: never = never,
|
||||||
|
> = DefaultSchemaTableNameOrOptions extends {
|
||||||
|
schema: keyof DatabaseWithoutInternals
|
||||||
|
}
|
||||||
|
? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends {
|
||||||
|
Insert: infer I
|
||||||
|
}
|
||||||
|
? I
|
||||||
|
: never
|
||||||
|
: DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"]
|
||||||
|
? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends {
|
||||||
|
Insert: infer I
|
||||||
|
}
|
||||||
|
? I
|
||||||
|
: never
|
||||||
|
: never
|
||||||
|
|
||||||
|
export type TablesUpdate<
|
||||||
|
DefaultSchemaTableNameOrOptions extends
|
||||||
|
| keyof DefaultSchema["Tables"]
|
||||||
|
| { schema: keyof DatabaseWithoutInternals },
|
||||||
|
TableName extends DefaultSchemaTableNameOrOptions extends {
|
||||||
|
schema: keyof DatabaseWithoutInternals
|
||||||
|
}
|
||||||
|
? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"]
|
||||||
|
: never = never,
|
||||||
|
> = DefaultSchemaTableNameOrOptions extends {
|
||||||
|
schema: keyof DatabaseWithoutInternals
|
||||||
|
}
|
||||||
|
? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends {
|
||||||
|
Update: infer U
|
||||||
|
}
|
||||||
|
? U
|
||||||
|
: never
|
||||||
|
: DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"]
|
||||||
|
? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends {
|
||||||
|
Update: infer U
|
||||||
|
}
|
||||||
|
? U
|
||||||
|
: never
|
||||||
|
: never
|
||||||
|
|
||||||
|
export type Enums<
|
||||||
|
DefaultSchemaEnumNameOrOptions extends
|
||||||
|
| keyof DefaultSchema["Enums"]
|
||||||
|
| { schema: keyof DatabaseWithoutInternals },
|
||||||
|
EnumName extends DefaultSchemaEnumNameOrOptions extends {
|
||||||
|
schema: keyof DatabaseWithoutInternals
|
||||||
|
}
|
||||||
|
? keyof DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"]
|
||||||
|
: never = never,
|
||||||
|
> = DefaultSchemaEnumNameOrOptions extends {
|
||||||
|
schema: keyof DatabaseWithoutInternals
|
||||||
|
}
|
||||||
|
? DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"][EnumName]
|
||||||
|
: DefaultSchemaEnumNameOrOptions extends keyof DefaultSchema["Enums"]
|
||||||
|
? DefaultSchema["Enums"][DefaultSchemaEnumNameOrOptions]
|
||||||
|
: never
|
||||||
|
|
||||||
|
export type CompositeTypes<
|
||||||
|
PublicCompositeTypeNameOrOptions extends
|
||||||
|
| keyof DefaultSchema["CompositeTypes"]
|
||||||
|
| { schema: keyof DatabaseWithoutInternals },
|
||||||
|
CompositeTypeName extends PublicCompositeTypeNameOrOptions extends {
|
||||||
|
schema: keyof DatabaseWithoutInternals
|
||||||
|
}
|
||||||
|
? keyof DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"]
|
||||||
|
: never = never,
|
||||||
|
> = PublicCompositeTypeNameOrOptions extends {
|
||||||
|
schema: keyof DatabaseWithoutInternals
|
||||||
|
}
|
||||||
|
? DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"][CompositeTypeName]
|
||||||
|
: PublicCompositeTypeNameOrOptions extends keyof DefaultSchema["CompositeTypes"]
|
||||||
|
? DefaultSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions]
|
||||||
|
: never
|
||||||
|
|
||||||
|
export const Constants = {
|
||||||
|
public: {
|
||||||
|
Enums: {},
|
||||||
|
},
|
||||||
|
} as const
|
||||||
1
supabase/config.toml
Normal file
1
supabase/config.toml
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
project_id = "smsarmgoirlcedmqvdgc"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue