feat: create user image retrieval API endpoint feat: enhance coin page with dynamic data fetching and improved UI feat: implement coin creation form with validation and submission logic feat: add user settings page with profile update functionality
83 lines
No EOL
3.2 KiB
TypeScript
83 lines
No EOL
3.2 KiB
TypeScript
// src/lib/auth.ts (or your auth config file)
|
|
import { betterAuth } from "better-auth";
|
|
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
|
import { env } from '$env/dynamic/private';
|
|
import { db } from "./server/db";
|
|
import * as schema from "./server/db/schema";
|
|
import { generateUsername } from "./utils/random";
|
|
import { uploadProfilePicture } from "./server/s3";
|
|
|
|
if (!env.GOOGLE_CLIENT_ID) throw new Error('GOOGLE_CLIENT_ID is not set');
|
|
if (!env.GOOGLE_CLIENT_SECRET) throw new Error('GOOGLE_CLIENT_SECRET is not set');
|
|
|
|
export const auth = betterAuth({
|
|
baseURL: env.PUBLIC_BETTER_AUTH_URL,
|
|
secret: env.PRIVATE_BETTER_AUTH_SECRET,
|
|
appName: "Rugplay",
|
|
|
|
database: drizzleAdapter(db, {
|
|
provider: "pg",
|
|
schema: schema,
|
|
}),
|
|
socialProviders: {
|
|
google: {
|
|
clientId: env.GOOGLE_CLIENT_ID,
|
|
clientSecret: env.GOOGLE_CLIENT_SECRET,
|
|
mapProfileToUser: async (profile) => {
|
|
const newUsername = generateUsername();
|
|
let s3ImageKey: string | null = null;
|
|
|
|
if (profile.picture) {
|
|
try {
|
|
const response = await fetch(profile.picture);
|
|
if (!response.ok) {
|
|
console.error(`Failed to fetch profile picture: ${response.statusText}`);
|
|
} else {
|
|
const blob = await response.blob();
|
|
const arrayBuffer = await blob.arrayBuffer();
|
|
s3ImageKey = await uploadProfilePicture(
|
|
profile.sub, // Using Google 'sub' for a unique identifier
|
|
new Uint8Array(arrayBuffer),
|
|
blob.type,
|
|
blob.size
|
|
);
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to upload profile picture during social login:', error);
|
|
}
|
|
}
|
|
|
|
return {
|
|
name: profile.name,
|
|
email: profile.email,
|
|
image: s3ImageKey, // Store S3 key in the standard 'image' field
|
|
username: newUsername,
|
|
};
|
|
},
|
|
}
|
|
},
|
|
user: {
|
|
additionalFields: {
|
|
username: { type: "string", required: true, input: false },
|
|
isAdmin: { type: "boolean", required: false, input: false },
|
|
isBanned: { type: "boolean", required: false, input: false },
|
|
banReason: { type: "string", required: false, input: false },
|
|
baseCurrencyBalance: { type: "string", required: false, input: false },
|
|
bio: { type: "string", required: false },
|
|
// Ensure 'image' is not listed here if it's a core field,
|
|
// or ensure 'avatarUrl' is used consistently if it is an additional field.
|
|
// Based on current setup, 'image' is core.
|
|
}
|
|
},
|
|
session: {
|
|
cookieCache: {
|
|
enabled: true,
|
|
maxAge: 60 * 5,
|
|
}
|
|
},
|
|
advanced: {
|
|
database: {
|
|
generateId: false,
|
|
}
|
|
}
|
|
}); |