@@ -4,6 +4,7 @@ import { createAuthMiddleware } from "better-auth/api";
4
4
import { apiKey } from "better-auth/plugins" ;
5
5
import { magicLink } from "better-auth/plugins/magic-link" ;
6
6
import { env } from "next-runtime-env" ;
7
+ import { PutObjectCommand , S3Client } from "@aws-sdk/client-s3" ;
7
8
8
9
import type { dbClient } from "@kan/db/client" ;
9
10
import * as memberRepo from "@kan/db/repository/member.repo" ;
@@ -12,6 +13,14 @@ import * as schema from "@kan/db/schema";
12
13
import { sendEmail } from "@kan/email" ;
13
14
import { createStripeClient } from "@kan/stripe" ;
14
15
16
+ async function downloadImage ( url : string ) : Promise < Buffer > {
17
+ const response = await fetch ( url ) ;
18
+ if ( ! response . ok ) {
19
+ throw new Error ( `Failed to download image: ${ response . statusText } ` ) ;
20
+ }
21
+ return Buffer . from ( await response . arrayBuffer ( ) ) ;
22
+ }
23
+
15
24
export const initAuth = ( db : dbClient ) => {
16
25
return betterAuth ( {
17
26
secret : process . env . BETTER_AUTH_SECRET ! ,
@@ -65,6 +74,49 @@ export const initAuth = (db: dbClient) => {
65
74
} ,
66
75
} ) ,
67
76
] ,
77
+ databaseHooks : {
78
+ user : {
79
+ create : {
80
+ async before ( user , context ) {
81
+ const newUser = { ...user } ;
82
+ if ( user . image && ! user . image . includes ( process . env . NEXT_PUBLIC_STORAGE_DOMAIN ! ) ) {
83
+ try {
84
+ const client = new S3Client ( {
85
+ region : env ( "S3_REGION" ) ?? "" ,
86
+ endpoint : env ( "S3_ENDPOINT" ) ?? "" ,
87
+ credentials : {
88
+ accessKeyId : env ( "S3_ACCESS_KEY_ID" ) ?? "" ,
89
+ secretAccessKey : env ( "S3_SECRET_ACCESS_KEY" ) ?? "" ,
90
+ } ,
91
+ } ) ;
92
+
93
+ console . log ( user . image ) ;
94
+
95
+ const allowedFileExtensions = [ "jpg" , "jpeg" , "png" , "webp" ] ;
96
+
97
+ const fileExtension = user . image . split ( '.' ) . pop ( ) ?. split ( '?' ) [ 0 ] || 'jpg' ;
98
+ const key = `${ Date . now ( ) } -${ Math . random ( ) . toString ( 36 ) . substring ( 2 , 15 ) } .${ ! allowedFileExtensions . includes ( fileExtension ) ? 'jpg' : fileExtension } ` ;
99
+
100
+ const imageBuffer = await downloadImage ( user . image ) ;
101
+
102
+ await client . send ( new PutObjectCommand ( {
103
+ Bucket : env ( "NEXT_PUBLIC_AVATAR_BUCKET_NAME" ) ?? "" ,
104
+ Key : key ,
105
+ Body : imageBuffer ,
106
+ ContentType : `image/${ ! allowedFileExtensions . includes ( fileExtension ) ? 'jpeg' : fileExtension } ` ,
107
+ ACL : 'public-read' ,
108
+ } ) ) ;
109
+
110
+ newUser . image = key ;
111
+ } catch ( error ) {
112
+ console . error ( error ) ;
113
+ }
114
+ }
115
+ return { data : newUser } ;
116
+ }
117
+ }
118
+ }
119
+ } ,
68
120
hooks : {
69
121
after : createAuthMiddleware ( async ( ctx ) => {
70
122
if ( ctx . path . startsWith ( "/get-session" ) ) {
0 commit comments