mirror of
https://github.com/domfelipe/mika-agent-assist.git
synced 2026-08-07 08:16:41 +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-group": "^1.1.11",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@supabase/supabase-js": "^2.103.3",
|
||||
"@tailwindcss/vite": "^4.2.1",
|
||||
"@tanstack/react-query": "^5.99.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