mirror of
https://github.com/Mail-0/Zero.git
synced 2026-06-28 14:56:48 +00:00
feat: seprate twilio service
This commit is contained in:
@@ -31,4 +31,6 @@ NODE_ENV="development"
|
||||
|
||||
AUTUMN_SECRET_KEY=
|
||||
|
||||
PERPLEXITY_API_KEY=
|
||||
TWILIO_ACCOUNT_SID=
|
||||
TWILIO_AUTH_TOKEN=
|
||||
TWILIO_PHONE_NUMBER=
|
||||
@@ -12,10 +12,10 @@ import { defaultUserSettings } from '@zero/db/user_settings_default';
|
||||
import { getBrowserTimezone, isValidTimezone } from './timezones';
|
||||
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
|
||||
import { getSocialProviders } from './auth-providers';
|
||||
import { redis, resend, twilio } from './services';
|
||||
import { getContext } from 'hono/context-storage';
|
||||
import { getActiveDriver } from './driver/utils';
|
||||
import { APIError } from 'better-auth/api';
|
||||
import { redis, resend } from './services';
|
||||
import type { HonoContext } from '../ctx';
|
||||
import { env } from 'cloudflare:workers';
|
||||
import { createDriver } from './driver';
|
||||
@@ -79,39 +79,23 @@ const connectionHandlerHook = async (account: Account) => {
|
||||
|
||||
export const createAuth = () => {
|
||||
const c = getContext<HonoContext>();
|
||||
const twilioClient = twilio();
|
||||
|
||||
return betterAuth({
|
||||
plugins: [
|
||||
phoneNumber({
|
||||
sendOTP: async (data) => {
|
||||
if (!env.TWILIO_ACCOUNT_SID || !env.TWILIO_AUTH_TOKEN || !env.TWILIO_PHONE_NUMBER) {
|
||||
throw new APIError('INTERNAL_SERVER_ERROR', {
|
||||
message: 'Twilio configuration missing',
|
||||
await twilioClient.messages
|
||||
.send(
|
||||
data.phoneNumber,
|
||||
`Your verification code is: ${data.code}, do not share it with anyone.`,
|
||||
)
|
||||
.catch((error) => {
|
||||
console.error('Failed to send OTP', error);
|
||||
throw new APIError('INTERNAL_SERVER_ERROR', {
|
||||
message: `Failed to send OTP, ${error.message}`,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`https://api.twilio.com/2010-04-01/Accounts/${env.TWILIO_ACCOUNT_SID}/Messages.json`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
Authorization: `Basic ${btoa(`${env.TWILIO_ACCOUNT_SID}:${env.TWILIO_AUTH_TOKEN}`)}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
To: data.phoneNumber,
|
||||
From: env.TWILIO_PHONE_NUMBER,
|
||||
Body: `Your verification code is: ${data.code}, do not share it with anyone.`,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
throw new APIError('INTERNAL_SERVER_ERROR', {
|
||||
message: `Failed to send OTP: ${error}`,
|
||||
});
|
||||
}
|
||||
},
|
||||
}),
|
||||
],
|
||||
|
||||
@@ -8,3 +8,47 @@ export const resend = () =>
|
||||
: { emails: { send: async (...args: unknown[]) => console.log(args) } };
|
||||
|
||||
export const redis = () => new Redis({ url: env.REDIS_URL, token: env.REDIS_TOKEN });
|
||||
|
||||
export const twilio = (forceUseRealService = false) => {
|
||||
if (env.NODE_ENV === 'development' && !forceUseRealService) {
|
||||
return {
|
||||
messages: {
|
||||
send: async (to: string, body: string) =>
|
||||
console.log(`[TWILIO:MOCK] Sending message to ${to}: ${body}`),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (!env.TWILIO_ACCOUNT_SID || !env.TWILIO_AUTH_TOKEN || !env.TWILIO_PHONE_NUMBER) {
|
||||
throw new Error('Twilio is not configured correctly');
|
||||
}
|
||||
|
||||
const send = async (to: string, body: string) => {
|
||||
const response = await fetch(
|
||||
`https://api.twilio.com/2010-04-01/Accounts/${env.TWILIO_ACCOUNT_SID}/Messages.json`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
Authorization: `Basic ${btoa(`${env.TWILIO_ACCOUNT_SID}:${env.TWILIO_AUTH_TOKEN}`)}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
To: to,
|
||||
From: env.TWILIO_PHONE_NUMBER,
|
||||
Body: body,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
throw new Error(`Failed to send OTP: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
messages: {
|
||||
send,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user