216 lines
5.0 KiB
TypeScript
216 lines
5.0 KiB
TypeScript
import { EnvMode } from '@/app/variables/lib/types';
|
|
|
|
import { getVariable } from '../variables/lib/env-scanner';
|
|
|
|
export function createConnectivityService(mode: EnvMode) {
|
|
return new ConnectivityService(mode);
|
|
}
|
|
|
|
class ConnectivityService {
|
|
constructor(private mode: EnvMode = 'development') {}
|
|
|
|
async checkSupabaseConnectivity() {
|
|
const url = await getVariable('NEXT_PUBLIC_SUPABASE_URL', this.mode);
|
|
|
|
if (!url) {
|
|
return {
|
|
status: 'error' as const,
|
|
message: 'No Supabase URL found in environment variables',
|
|
};
|
|
}
|
|
|
|
const anonKey = await getVariable(
|
|
'NEXT_PUBLIC_SUPABASE_ANON_KEY',
|
|
this.mode,
|
|
);
|
|
|
|
if (!anonKey) {
|
|
return {
|
|
status: 'error' as const,
|
|
message: 'No Supabase Anon Key found in environment variables',
|
|
};
|
|
}
|
|
|
|
const response = await fetch(`${url}/auth/v1/health`, {
|
|
headers: {
|
|
apikey: anonKey,
|
|
Authorization: `Bearer ${anonKey}`,
|
|
},
|
|
});
|
|
|
|
if (!response.ok) {
|
|
return {
|
|
status: 'error' as const,
|
|
message:
|
|
'Failed to connect to Supabase. The Supabase Anon Key or URL is not valid.',
|
|
};
|
|
}
|
|
|
|
return {
|
|
status: 'success' as const,
|
|
message: 'Connected to Supabase',
|
|
};
|
|
}
|
|
|
|
async checkSupabaseAdminConnectivity() {
|
|
const url = await getVariable('NEXT_PUBLIC_SUPABASE_URL', this.mode);
|
|
|
|
if (!url) {
|
|
return {
|
|
status: 'error' as const,
|
|
message: 'No Supabase URL found in environment variables',
|
|
};
|
|
}
|
|
|
|
const endpoint = `${url}/rest/v1/accounts`;
|
|
|
|
const apikey = await getVariable(
|
|
'NEXT_PUBLIC_SUPABASE_ANON_KEY',
|
|
this.mode,
|
|
);
|
|
|
|
if (!apikey) {
|
|
return {
|
|
status: 'error' as const,
|
|
message: 'No Supabase Anon Key found in environment variables',
|
|
};
|
|
}
|
|
|
|
const adminKey = await getVariable('SUPABASE_SERVICE_ROLE_KEY', this.mode);
|
|
|
|
if (!adminKey) {
|
|
return {
|
|
status: 'error' as const,
|
|
message: 'No Supabase Service Role Key found in environment variables',
|
|
};
|
|
}
|
|
|
|
const response = await fetch(endpoint, {
|
|
headers: {
|
|
apikey,
|
|
Authorization: `Bearer ${adminKey}`,
|
|
},
|
|
});
|
|
|
|
if (!response.ok) {
|
|
return {
|
|
status: 'error' as const,
|
|
message:
|
|
'Failed to connect to Supabase Admin. The Supabase Service Role Key is not valid.',
|
|
};
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.length === 0) {
|
|
return {
|
|
status: 'error' as const,
|
|
message:
|
|
'No accounts found in Supabase Admin. The data may not be seeded. Please run `pnpm run supabase:web:reset` to reset the database.',
|
|
};
|
|
}
|
|
|
|
return {
|
|
status: 'success' as const,
|
|
message: 'Connected to Supabase Admin',
|
|
};
|
|
}
|
|
|
|
async checkStripeWebhookEndpoints() {
|
|
const secretKey = await getVariable('STRIPE_SECRET_KEY', this.mode);
|
|
|
|
if (!secretKey) {
|
|
return {
|
|
status: 'error' as const,
|
|
message: 'No Stripe Secret Key found in environment variables',
|
|
};
|
|
}
|
|
|
|
const webhooksSecret = await getVariable(
|
|
'STRIPE_WEBHOOK_SECRET',
|
|
this.mode,
|
|
);
|
|
|
|
if (!webhooksSecret) {
|
|
return {
|
|
status: 'error' as const,
|
|
message: 'No Webhooks secret found in environment variables',
|
|
};
|
|
}
|
|
|
|
const url = `https://api.stripe.com`;
|
|
|
|
const request = await fetch(`${url}/v1/webhook_endpoints`, {
|
|
headers: {
|
|
Authorization: `Bearer ${secretKey}`,
|
|
},
|
|
});
|
|
|
|
if (!request.ok) {
|
|
return {
|
|
status: 'error' as const,
|
|
message:
|
|
'Failed to connect to Stripe. The Stripe Webhook Secret is not valid.',
|
|
};
|
|
}
|
|
|
|
const webhooksResponse = await request.json();
|
|
const webhooks = webhooksResponse.data ?? [];
|
|
|
|
if (webhooks.length === 0) {
|
|
return {
|
|
status: 'error' as const,
|
|
message: 'No webhooks found in Stripe',
|
|
};
|
|
}
|
|
|
|
const allWebhooksShareTheSameSecret = webhooks.every(
|
|
(webhook: { secret: string }) => webhook.secret === webhooksSecret,
|
|
);
|
|
|
|
if (!allWebhooksShareTheSameSecret) {
|
|
return {
|
|
status: 'error' as const,
|
|
message: 'All webhooks do not share the same secret',
|
|
};
|
|
}
|
|
|
|
return {
|
|
status: 'success' as const,
|
|
message: 'All webhooks share the same Webhooks secret',
|
|
};
|
|
}
|
|
|
|
async checkStripeConnected() {
|
|
const secretKey = await getVariable('STRIPE_SECRET_KEY', this.mode);
|
|
|
|
if (!secretKey) {
|
|
return {
|
|
status: 'error' as const,
|
|
message: 'No Stripe Secret Key found in environment variables',
|
|
};
|
|
}
|
|
|
|
const url = `https://api.stripe.com`;
|
|
|
|
const request = await fetch(`${url}/v1/prices`, {
|
|
headers: {
|
|
Authorization: `Bearer ${secretKey}`,
|
|
},
|
|
});
|
|
|
|
if (!request.ok) {
|
|
return {
|
|
status: 'error' as const,
|
|
message:
|
|
'Failed to connect to Stripe. The Stripe Secret Key is not valid.',
|
|
};
|
|
}
|
|
|
|
return {
|
|
status: 'success' as const,
|
|
message: 'Connected to Stripe',
|
|
};
|
|
}
|
|
}
|