From fc5c2f0eab52df5a4353e5c399f03bd022d3ce49 Mon Sep 17 00:00:00 2001 From: Saimon8420 Date: Mon, 27 Jan 2025 18:19:02 +0600 Subject: [PATCH] auth added not tested yet --- bun.lockb | Bin 80307 -> 87120 bytes ..._marvel_zombies.sql => 0000_tidy_echo.sql} | 5 +- drizzle/0001_shallow_umar.sql | 4 + drizzle/0001_useful_nighthawk.sql | 2 - drizzle/0002_broad_eternity.sql | 1 - drizzle/meta/0000_snapshot.json | 14 +- drizzle/meta/0001_snapshot.json | 36 +++- drizzle/meta/0002_snapshot.json | 188 ------------------ drizzle/meta/_journal.json | 15 +- package.json | 2 + src/api/auth/auth.controller.ts | 129 +++++++++--- src/api/auth/auth.route.ts | 11 +- src/api/index.ts | 3 +- src/app.ts | 5 +- src/config/env.ts | 2 + src/db/schema.ts | 5 + src/helper/auth/auth.helper.ts | 51 +++++ 17 files changed, 230 insertions(+), 243 deletions(-) rename drizzle/{0000_eager_marvel_zombies.sql => 0000_tidy_echo.sql} (94%) create mode 100644 drizzle/0001_shallow_umar.sql delete mode 100644 drizzle/0001_useful_nighthawk.sql delete mode 100644 drizzle/0002_broad_eternity.sql delete mode 100644 drizzle/meta/0002_snapshot.json create mode 100644 src/helper/auth/auth.helper.ts diff --git a/bun.lockb b/bun.lockb index a4ac9357708e8f47c7776cd12c67f1dc8c8ac7e4..1b1c7bdc8cfe79d77bda9770110c93ccf460aaed 100644 GIT binary patch delta 16781 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�|8|2qMxXBJ8@o0tc=(2h;&%pJZG30dikd4ojdY(GpQXJt z=#A69LF*?U`?FiKDz)ossT-b6$COzn$7j2(wzzD5V7S>cA>r1_2Xn6WQV!fOJ2-CI ztI0pQzIbm{+Hcx@Ej=F&ni79|Y3;BUBe(6^vwZjQr`!He)tE+8Mrll~3pal8+Wyj` zk4(9TUoQE&sFufwZ{OC<^%|HwtZ_oSZZE>WaqcmB$Y<}o>2qgpMAw+uW4Z~(Vf{|*_V3bS z@z=A}ky>A4@(gNrYE!?${mZ=f1+93{=kSHDwigE+Bi}TQDei~p`zsFF{y6Y!Rs7@P zz^IVK)F;b_UFy|yvFGedb$U+9FYuaF(s0a>vjaj?Hk^LEJ-6|Qkl=#u@c~`e<^Ebb zOjo6L@^4wLq4hH33WL$M^n>?0NA2x5wO8h^X)XT@-aW+HWEe&(SwG1G@1?Aq%VT|n)IOz3Ch{zYI!a^I*P(UadM=iHm~ zQ|ZyW*2Xo@Hb;J6dR=?ie$N+;PWB#u%6`lC2^TWol#G8t(^ib_8+XPr;g?eB#a5bk zz2%PM+I`jd)LTtkhaL+Qi)YNP=Q{D=qo>wS_9yhYH|fb2>yP@*$_hPm`BhCn?YdX{ z?uYKQ)j5B(d(8R-Q+)sWGZvn|J8pd}%^j^VeYVQ$f>X=1bFYfj?oA6v-#Xgw*IzSR zc|8B&{HuMJ`dxY2$?c+{b#X_>?W?9Mk4{s5wm9A|X+nf>D)mO+=nefFWL4=qW7XOn zbm=uay5U=Gq$2Wz0P9~KzliDe>e`ruW5+hm-rKSHyrHp+CLHUX-A(H{>C%p*^n&81 zyB~I1yE67<<4$>dj~N{!gDECmL)YiT3;n1()kwdm+fm5Kc>MWk>PRE4%CMvBhz+E` zQAX;UX-6N9iWde`1!6W?cGNB{UPz>(G$U=|N7)Oxg$MvSqeFGj};$@Cjynru7j zogOcw(6V$R?L$nJ5ig`t_Y5PA&#|LTh>ap4(?~6H?M&+UcXpk$UV1^uvO79;;jXLh zDPM04FKpOKSI@7-%FYYo@A#c5iVeH-bZMKlyZhYw@yO9*dyf>Cud(@Qbe~siKV4F* zN>7ch+EaCYSl4sMgAcv#*6Ho+{ND64L4m#B_53z->Ezlp?M$@c^O?gVj6NIZXeZ5z zi~T&Tre@pju(iXd8od&|LWU&8kn2o3n5!`*e)daG@3+hMd9?T><-@$o4_&rSYqC9} zc1}j{OikKR$ZYPRcm+p z)~MuxbNb{e2F3MquJv*E$fhIvnsVE}Ubkk_k?Y%QHmUn_VgIeq^Rz`z;)`=%j99ch z>Em^eeb4vwsWt3vyCr$|6KKj<4V_pJFJzJDhsJ(msycsYxY%L&_cu@L`sO#;{-}?0 zP_OnW&zC+L-pqKSe`og@2`LBOU%u0|-mFdUf84sk<)Re#YhjbzTa-mzY8j^U>b8r2 zg2`KQHub|e-5O^{J2K<(Cqs3XQ5Z{!pyOy8=y-A*V-zM(D(FPo1v-he*+yY9Wr0qi zGSEEo%rW9`o)bXxsT_1FdFL91_h>5UG&%!1odU-ig&9-;I+H3uXHmpBqcEF_Knv(L zXd$&8ZxrUxC!p`sZ=iE2Zh}#mN6SDzpqHTYsry8uP(-Uii%FPd6o~qPE}#vdACh{q zQTT`wK}%>G=*Q$Z#fU$|rGhS`U7(+mHqR(5qAbwQs0?&5d76yE5}E+Il*&Puk$1jP z_?)JKE~hh~D=2WP5r3R50R56GKvz=4dq!au6@jj%+n`@j>uE+|4SfQ-mVN{Mn&PG# zg>|$HbUnQU{f4^FFbW%JHR!h_%rpucsUK)5Z2;Xw>RCo%GbMs

3dB$#J$(*hZOS8n9HG^qP=+VdHStB2-`Jp+E(@^Wh1|-t_FKtvO@F$^KFulqS==Jh^OUer|rK-(2 z<;JC}hqc)F=;JX~whq^%HF)|O*&mHIy?HAIPUO#pSXAOq-l}naOXZ(%9M%J}jlGzn zP<&%f0bg@DVZbQ_L=K{>BppL<2E^9xwp00QU@k+~PMqf1o+w2Q&r( zfEIu|;0-hZ0)ZgF2jDlHmVk$VFQ-i*v;rCdzJM3t3GlCy-%&^fa1=NR90!g8?9kp9AXu59;76*VkkJ5nGEn~rvNR`PGC#}c%4rL@&R@-1u$=?Z+WJ%p7(?4X7F^L4e**N zpwzQbT^2whpcp6u<^vx9^MJX)`@kGv53mc^39JCv%NM|E;7ec?u#(Eoz7w||(mLR4 zU@fo)_zKt!aQS_Kv%nePG;j(y37i0q1IK`)Ksg1Tt7kd@=~rMsPzLM+_5!~EKLbAj z=K=0g#ziw%f!7AE1J{5nKm~9axCC4U#DxJ?%5xUMHhO?AbYO0{zL74pQFiLYKr*cpo8TzZAxKKfM2*@0RLtAk8@hVNDa;h2_q=(d>2hNe4xyH`3xRxBm4sVbhP07 zVppz2Ehs+-dFb>w`|kLXql+uBE#(D5AIxVhtS(Mk-~g3!Av%DkjgHc-)uOFn`p9lqqr zzk@CXDP3w%v&*`WRW+pUb9ge%!MRyRh`9o2fP8TLMa{CYLpH7LYu1EeO3>WPT37jG zeBZV2KK4xOaa_~~`suJ&)2_=}A&$<0_MogAPE@NR3``Z zeK*(2GUr8wZ&Fc(R(L~eKqa{gm0xqRM!N@->8ci^{^u1f-tX~=2=C>iuWM<@6&JXj zbR`IH-0NkXt9*|B+x0c*cwqZE=IX!BMch)&sW2m?WT37i* z|Go7w%j$3H-9mJz(F3?*Q!O>V;UZcENpUHM5(hiKyrByn>L5+#?~dLW zx+=SLmbur_CGzS2&x1}TEcxOkPavMg(A01w`#zET2JkR+LYCg#GCN$>lK)%8t9}-py=Al!_mmK6{#Ab~+s(3LJ=MhVEe2nO|F(5#;I>BVbOzL5+9F^ktjQy-dk z?K-|cxxV!XNyAOw<3@|_XxvW2paBdVx(qJ)t;gc1%2MyU(GmDoHk9u1s8TwOx>T!W z1$)4hLvS%`;_4`hyEWU8RavU8A-UhxgvP@FZ;AQdZTG}F{=DiX8(=gLu}lL+Tb=2fM$#zBr_05HLwEx3fW{e>mCvJ##fVSBYUWh{mN90}apd8F zkY$7=Yf|5`6i5f;9Y5%C{H~p?RO1*elIvwzSdG_xlQ&y zlgBl94)zPi9$~ovW9oeEih9;}q0nHn!Cn}AtTENTuT$dUOzeG)(!UAyzn`z{+LX@U zUl?lRC9Qz=&Fk#D+o97dr4WP_jXqTT^O79BXzc?ZHxFd>KqK{L7n3wmuTp3A8eU)U z@S?{LB9#Z5k>5ifw`s(zxXE`h0@^Gbyro7RWu?J%Z_0n936(G4%(h-TVz6W6 z_(}u$ijIw=zU5Y7!GTK64sSYytn!^6&8t^|J@$ttR~pE7V0J4WbZB;48C$7&=}m6G zY24&%LOyj{1PODlE~_-~^r3FQX+q_TMHF?f$;i12XIC1?SC95R&-a+TqBm7)2Kvxq zWR>qK_0S(_>DJJ3Wu<|9o5{|(?d`?u#_p}uEcT&$sFr+nCT+;)Z%-C&Yh7uu--jAK z)+jIgP~>Bs@_8VoKh}iGS8@h-TzX)-^BxZjDJCRuz0!3gMZW#Y17CD6xiD0mtsy+| zFdM#yqlr2?`B)b!-%|R>A-{Fdz;*3J4 z^F}_f@j6;*P~CKqe1GLl_D?mT@&&JbHM^CxzcqSyW!CDZiIKWr2dsz ztD7!T*4aMP>Y2t(z6-aeed@q5hUSYZvzGeMkZ0ngnE0%%vOJP@K5OJw-D(bu@C(%O zYJLrW)eetnfZ+*vt_iJnctnHhRmZn2V7u);_uI@Jbu*Z{KD6J(#+p=u75X>-+HdmvEPGS zOWR0q-}8eR#zVS+_uY78c%+5$3mpn8lV^nfFW&PP?7Y!*|~lhSgBC1=agY}^kXnmoo5#f{qAo|>MMoFbY#u;bM1%(TSRbX;UjPAb{uAh-ouEGrc`s9tr+zWfs*ls5e7;bl>q z{a4LlPVx;dsZa||np;fGRjX=hPV&XOKuK#y!Ly0QSZY>PTPX!zcdCRYl@*Y>qpG2l zV)5xI`!siC6;pFc$vlnV6<{{wuCFxV7@E!BJTN*#Q`7yW-&B4hvr7_d2n`+i_B70; zRNpYaP_Z3$_)UgXP*g)#a>Q2f)Z=Egn3U)%{$dgR~x zzB#F*larH%WheS(r>6Mg{`}~~oE)0^wxR#uQpK{XNktJ@B_+Rk2#rd*)Ddb1R8s^h zgX^0Aqpc_^T_d%B3r?&`Ck&bQ4gbFpb>I)^hzbHRprE2NZs7uEnl)~zps3)2inyi>E~%+0-s)(X zxnv10>5EIIl2UhP^U{zuJ`X>AtMl8d4c7hl3r@v`Y&V5B6B37$h4v8H z?Req%(AGaf^^hdT3GiCr2f=HAj~pB`X2QtK+*nzXe4vjXlR07_(!!v#eNAvra6{o& zN%#o%1n;GB`{TN;!z zIwmuHz>pMoH9isP?Dsr$E_9Sp%{L@HH)q@kN$L$9@%fG+5b)oTrWv%=^s&gz6*&wC z0pJ$I`+~>7G27QcVoh)YH-YDabACM-mxB9&Z-v4Q$jXfwojJHl z=J>hfBM0;>M;u3Y_g2kQG=2q~+j#^1!h95Zl&f`K>!la>tAwkvCkDN}zM^ysdd#s-@4-;?r{{j2M94&CbcqgI->Px6 zR~gA2=;;6qq$40&ZP7Szc5n`yd-@A-9`Zl8{QubEe{FC+3iwa8cnw;}T~6RUgab1( z@&=>z!*f9pxMBH!9Mi|zvPWxJzA~o&?pR_QQx?ZJ$?8yrwNNMR3Fy3Nu%HyKZ{X&Z z>RQk@@-R76T_pMro|BO`2zexftQvZ?EGe$mSEljRmzH#>;gH?m-1^a}ZC}psKnFbz zdKW&~YhL|rEt?s0S{%62_0?Upz;me>K#^WH@fu}$+2s2Y6?<8Qjmo@i#`!pJtf-Wr za<3%u8D)9fj5d_hNr@Zfog`*cnYT^sqDUW`@jg=8DJffgl0<7N^0A2-RECsYRU|19 zDOK2yTwaB;eXYg_H%V%YNH=0fJ*mvsCj2O}rp@>)&K)${QG?3iXaN<~w22R>4Ahq* zYuQ9^$^tE=qFOd%7i{$@N}=WOvXUbGY{s*Qi&Ns*vnLh#*+f?=L&|&{BpYow?EtDyxJS97}VlWdp@DTOwAC5wYp7GN{T zSZ=M9ls1r_SEQwo(pZu&)}SjUtFTa{*=Ah-gt8}d*{D?&Dl*#)&tkjlPBA{o#(j|b zC^h5G3#P2vHbVv`LpQFK;X_DD{e+Ps18v6EI6zvtT3A3ufi}ZV#5JYs-pNK@I@~8! z$Wk-Om;p^47L;pvi#56)kZk-F5)ZC{EP+WPfg*!#VlriczE4HLHe++_EYBcaB8xf6 z@G`Vcv=Lo!5>h**Rwit2Em#uWsjQAo6jEe}4IPseVlzBIT5}rioh(wQEW{?yt)&e5 zUaammN}(89ql{xmZ3Y@`Yy*v}Ez=gSB;zb-Y$=n)FG+k#Sz$K$o*zX;SmkJc$_88L zPsI^d<4Nr4ZDIHXZ3#{?24I0ThbHl?GIoW=qp9?{JR^XL>s#d-X1Y?}YHWpL&DDp7 z*Pz8yOhB^ynVE_kSdEQv8uC1sxHfWLZHj7Wl}l<$AkWDvv?Vafm#VRcMrNlJU4JtvoWx=pO1?3P@`KEf$t2FCfWS3@rg#O~S~@--c3DoK+qi zM%i&z<7%A4Tx*P@Uy}TF7+pbRR9#8xfJmWam|T~#Emp&#dXn@s4Ywp4&O=I5q}T{u zn&^@axFp~DdTL)tos=BwAazirn=Ywo13k{+k`B5g?}mD650|vkC0&M;qShr+m&UlH z_gs<`#S4LJ-_9k?a!I8w$-9weCwFf|#YtBA^G0+9EH;{=np)-A(Uc8#HJXZ>S`7_i zuqu^#m>EM+&8&vk5z&QWnk5^qLF%kX%`gzE^pZaQ7Nk$rlpn ziq$IDZ%k1(t8p9_D$jg3vcx4Bi=g2)!;>f&OQkUt+pGqUCfpYrZOMi{kUA?;kxRPm zlG&ljN`QCuPh0d1qr*J5*~%KJvKxoU$B}@0?+4<3JGgQk^#(l zCH#?dJZ7;Hm~#a%U8Jf2dRB3W-c-ULITwhIQv!4LgAU-UGw)4G=z#JS2OYHt=4_Y> zu!A&!19Mz!q%HubcLg{wcLSaSxI(=F&esQE`+l0tk3!V9o`MX9eM}cmyYK#tCeNP#G80vXd>JJKn)2 z2o8l-&UuuVYw656-zrUK&dpn+>C9PQtLcB_T&uUV^mP*NzX%YN>K1{s<4pkf%NBqG zbD4&x2AJ9H4uIXf3vgiWPM@U)aJNhQm>^Wf+2=<}s><2R#{kD4)Z&?Q{2@(eZUW9} z`rmM+{6{fVT>Xuse=}Vz|8Fb6v*!}P{rIEC%QSu!oWmcvKXk#}@hCk1Q4Rk?cKMan zlv`Q_1#+2gTEWZ%pa*LDW8(Rb+u`5(eL}!b|uuo+gicm?-oA@t-DYk9I_(I56j~ujDYvSGxSM zpC%}bhjIwO%lEGj6SSWVANOhUNQVi^ok*=aCI9z8`R{@9-vj0U$$^4B?y(&xB|D$L zXr|$LsdRay2YsBEDms(TSUW8pnmcqu{ zX9srZ%g9JC>0J?N=P zsp17HoMb1{I1hSZN~-8bMN{l_5SmARsz|4v`F0vV-h$sROsda4*jUro1*(PWun7r8Wh23j}8gRaj=6?xR`CA%0)g`nf840JrTo@o~o zXc_24DhHiJ9cS6ai?j-KGTi~4LS1LuMLrdQI!L^17X{Q4bSiBDokqqvb}^mOL1)lT z(3i+(u3gNeEYMlB4|Fz}=h?-}GzxSM9Ri(8VXxT5JemOd3LOKTPm%NO_%*ixw2;06 zT}YM%c0n{7bP=5cT};gi?P3WPf;y=TbSbr7Xcx<98R)B24*D8(B)eEnt3Y3;JD@A5 z>ms{&gNi^`l2~jPtEeaFYT5$2hKx(>;!R2iT}wMb-y$EUUA#?MpzCNKXc3v0+C?#q z0$opsKsQj>GP~GF6F@hSG0!gEp<|FYQ{=05v4sji|3P1YmXPH&yVy#zLATL4(CyT0 zxn1m_LeO`q40I>8e%&tKqh+AGs2p@RbzEV`FRiOUKcG9Hd#LLhcCnX=K=+YYX&3vc zC+LT?1@t2_uCj}dDIN3x?F9XVd{*1>Yiq~Jc5#SSf#OF}#2lu5prvG9W5-YSqd-5W zL!d_}>`l8kN)tej(J|2D6uH(ePLvd^U2hOgOJdfCh?4Ku_K+#m%Z<`DyBm6k;g1t! zS#MKfytlaPICp@*bvVQO0DsdoJOP3*<_mi3a$R!2)U;

)Nfa}Zc{3F0O-R0g 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 yj statement-breakpoint CREATE TABLE "users" ( "user_id" text PRIMARY KEY NOT NULL, - "paid_status" text NOT NULL, - "expires_in" timestamp NOT NULL + "paid_status" text, + "expires_in" text, + "refresh_token" text ); --> statement-breakpoint ALTER TABLE "projects" ADD CONSTRAINT "projects_user_id_users_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("user_id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint diff --git a/drizzle/0001_shallow_umar.sql b/drizzle/0001_shallow_umar.sql new file mode 100644 index 0000000..4d97447 --- /dev/null +++ b/drizzle/0001_shallow_umar.sql @@ -0,0 +1,4 @@ +ALTER TABLE "users" ADD COLUMN "email" text NOT NULL;--> statement-breakpoint +ALTER TABLE "users" ADD COLUMN "last_name" text;--> statement-breakpoint +ALTER TABLE "users" ADD COLUMN "first_name" text;--> statement-breakpoint +ALTER TABLE "users" ADD COLUMN "image" text; \ No newline at end of file diff --git a/drizzle/0001_useful_nighthawk.sql b/drizzle/0001_useful_nighthawk.sql deleted file mode 100644 index 400f70a..0000000 --- a/drizzle/0001_useful_nighthawk.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE "users" ALTER COLUMN "paid_status" DROP NOT NULL;--> statement-breakpoint -ALTER TABLE "users" ALTER COLUMN "expires_in" DROP NOT NULL; \ No newline at end of file diff --git a/drizzle/0002_broad_eternity.sql b/drizzle/0002_broad_eternity.sql deleted file mode 100644 index 46be296..0000000 --- a/drizzle/0002_broad_eternity.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "users" ALTER COLUMN "expires_in" SET DATA TYPE text; \ No newline at end of file diff --git a/drizzle/meta/0000_snapshot.json b/drizzle/meta/0000_snapshot.json index 405a5c4..8849ab9 100644 --- a/drizzle/meta/0000_snapshot.json +++ b/drizzle/meta/0000_snapshot.json @@ -1,5 +1,5 @@ { - "id": "7a9f9e79-63fc-4d2b-8b25-616f96161308", + "id": "a0fe5e52-63bf-4a92-adb0-ae296fb9f33e", "prevId": "00000000-0000-0000-0000-000000000000", "version": "7", "dialect": "postgresql", @@ -156,13 +156,19 @@ "name": "paid_status", "type": "text", "primaryKey": false, - "notNull": true + "notNull": false }, "expires_in": { "name": "expires_in", - "type": "timestamp", + "type": "text", "primaryKey": false, - "notNull": true + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false } }, "indexes": {}, diff --git a/drizzle/meta/0001_snapshot.json b/drizzle/meta/0001_snapshot.json index 4d52a9a..ff6944c 100644 --- a/drizzle/meta/0001_snapshot.json +++ b/drizzle/meta/0001_snapshot.json @@ -1,6 +1,6 @@ { - "id": "5443181c-129a-488a-9001-d65b03b0119f", - "prevId": "7a9f9e79-63fc-4d2b-8b25-616f96161308", + "id": "b6897b47-e0f0-48c5-8917-696944c8524b", + "prevId": "a0fe5e52-63bf-4a92-adb0-ae296fb9f33e", "version": "7", "dialect": "postgresql", "tables": { @@ -152,6 +152,30 @@ "primaryKey": true, "notNull": true }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "last_name": { + "name": "last_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "first_name": { + "name": "first_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, "paid_status": { "name": "paid_status", "type": "text", @@ -160,7 +184,13 @@ }, "expires_in": { "name": "expires_in", - "type": "timestamp", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", "primaryKey": false, "notNull": false } diff --git a/drizzle/meta/0002_snapshot.json b/drizzle/meta/0002_snapshot.json deleted file mode 100644 index 5ae009a..0000000 --- a/drizzle/meta/0002_snapshot.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "id": "88a4eebc-30cb-457f-9fc1-c6bbff735742", - "prevId": "5443181c-129a-488a-9001-d65b03b0119f", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.projects": { - "name": "projects", - "schema": "", - "columns": { - "project_id": { - "name": "project_id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "object": { - "name": "object", - "type": "json", - "primaryKey": false, - "notNull": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "projects_user_id_users_user_id_fk": { - "name": "projects_user_id_users_user_id_fk", - "tableFrom": "projects", - "tableTo": "users", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "user_id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.uploads": { - "name": "uploads", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "filename": { - "name": "filename", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "projectId": { - "name": "projectId", - "type": "uuid", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "uploads_projectId_projects_project_id_fk": { - "name": "uploads_projectId_projects_project_id_fk", - "tableFrom": "uploads", - "tableTo": "projects", - "columnsFrom": [ - "projectId" - ], - "columnsTo": [ - "project_id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.users": { - "name": "users", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "paid_status": { - "name": "paid_status", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "expires_in": { - "name": "expires_in", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 35f8261..fb24b31 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -5,22 +5,15 @@ { "idx": 0, "version": "7", - "when": 1737800628545, - "tag": "0000_eager_marvel_zombies", + "when": 1737876637906, + "tag": "0000_tidy_echo", "breakpoints": true }, { "idx": 1, "version": "7", - "when": 1737804031716, - "tag": "0001_useful_nighthawk", - "breakpoints": true - }, - { - "idx": 2, - "version": "7", - "when": 1737806743289, - "tag": "0002_broad_eternity", + "when": 1737876981144, + "tag": "0001_shallow_umar", "breakpoints": true } ] diff --git a/package.json b/package.json index 7529ed0..abb47f0 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,14 @@ }, "dependencies": { "@clerk/backend": "^1.23.7", + "@elysiajs/cookie": "^0.8.0", "@elysiajs/cors": "^1.2.0", "@elysiajs/swagger": "^1.2.0", "dotenv": "^16.4.7", "drizzle-orm": "^0.38.4", "elysia": "latest", "jose": "^5.9.6", + "jsonwebtoken": "^9.0.2", "minio": "^8.0.3", "pg": "^8.13.1", "postgres": "^3.4.5" diff --git a/src/api/auth/auth.controller.ts b/src/api/auth/auth.controller.ts index 5f5476c..eb91598 100644 --- a/src/api/auth/auth.controller.ts +++ b/src/api/auth/auth.controller.ts @@ -4,6 +4,11 @@ import { users } from "../../db/schema"; import { db } from "../../db"; import { eq } from "drizzle-orm"; +// @ts-ignore +import jwt from "jsonwebtoken"; + +import { checkUserInDB, createUser, storeRefreshToken } from "../../helper/auth/auth.helper"; + // Initialize Clerk with your API key const clerk = createClerkClient({ secretKey: ENV.CLERK_SECRET_KEY }); @@ -15,7 +20,18 @@ export const getUserData = async (userId: string) => { ]); if (user && !checkInDB.found) { - const userData = await createUser(user.id); + + // Validate and transform user data + const userDBData = { + id: user.id, + email: user.emailAddresses[0].emailAddress, // Assuming the first email address + firstName: user.firstName || "N/A", // Provide a default value if needed + lastName: user.lastName || "N/A", + image: user.imageUrl, + }; + + const userData = await createUser(userDBData); + return { status: 200, message: "User retrieved successfully", data: userData }; } if (user && checkInDB.found) { @@ -30,31 +46,6 @@ export const getUserData = async (userId: string) => { } }; -export const checkUserInDB = async (id: string) => { - try { - const user = await db.select().from(users).where(eq(users.id, id)); - return { status: 200, found: user?.length > 0 }; - } catch (error: any) { - console.error("Error in checkUserInDB:", error.message || error.toString()); - return { status: 500, message: `An error occurred while checking the user in DB` }; - } -}; - -export const createUser = async (id: string) => { - try { - const [saveUser] = await db.insert(users).values({ id }).returning({ insertedId: users.id }); - - if (!saveUser || !saveUser.insertedId) { - throw new Error("Failed to create user or missing insertedId"); - } - - return { status: 200, message: "User created successfully", data: saveUser.insertedId }; - } catch (error: any) { - console.error("Error in createUser:", error.message || error.toString()); - return { status: 500, message: `An error occurred while creating the user` }; - } -}; - export const updateUser = async (id: string, body) => { try { const updateUserData = await db.update(users).set({ paid_status: body?.paid_status, expires_in: body?.package_expire_date }).where(eq(users.id, id)).returning({ updatedId: users.id }); @@ -65,4 +56,88 @@ export const updateUser = async (id: string, body) => { console.error("Error in updateUser:", error.message || error.toString()); return { status: 500, message: `An error occurred while updating the user` }; } -} \ No newline at end of file +} + +export const generateToken = async (context: any) => { + try { + const userId = context?.params?.userId; + // generating accessToken and refreshToken + const user = await checkUserInDB(userId); + if (user?.found === true) { + const accessSecret = ENV.JWT_ACCESS_TOKEN_SECRET; + const refreshSecret = ENV.JWT_REFRESH_TOKEN_SECRET; + + // generate access token + const accessToken = jwt.sign({ userId }, accessSecret, { expiresIn: '3h' }); + + // generate refresh token + const refreshToken = jwt.sign({ userId }, refreshSecret, { expiresIn: '7d' }); + + // store refresh token in db + const storeRToken = await storeRefreshToken(userId, refreshToken); + + if (storeRToken.status === 200) { + context.cookie.access_token = { + value: accessToken, + httpOnly: true, + secure: true, + sameSite: 'none', + path: "/", + maxAge: 3 * 60 * 60 * 1000, // 3 hours + } + + return { status: 200, message: "Token generated successfully", token: accessToken }; + } + + return { status: 500, message: "An error occurred while storing the refresh token" }; + } + else { + return { status: 404, message: "Unauthorized!!!" }; + } + } catch (error: any) { + console.error("Error in generateToken:", error.message || error.toString()); + return { status: 500, message: `An error occurred while generating the token` }; + } +} + +export const verifyToken = async (context: any) => { + try { + // if token is in cookie, verify it + const token_cookie = context.cookie.access_token.value; + if (token_cookie) { + const verify_cookie = jwt.verify(token_cookie, ENV.JWT_REFRESH_TOKEN_SECRET); + if (verify_cookie) { + return { status: 200, message: "Token verified successfully" }; + } + else { + return { status: 401, message: "Unauthorized!!!" }; + } + } + // if token is not in cookie, then check in header and verify it + else { + const token_header = context.headers.authorization.split("Bearer ")[1]; + + if (token_header) { + const verify_header = jwt.decode(token_header); + + if (verify_header?.userId) { + context.params.userId = verify_header.userId; + await generateToken(context); + } + else { + return { status: 401, message: "Unauthorized!!!" }; + } + } + else { + return { status: 401, message: "Unauthorized!!!" }; + } + } + + } catch (error: any) { + console.log("Error in verifyToken:", error.message || error.toString()); + return { status: 500, message: `An error occurred while verifying the token` }; + } +} + + + diff --git a/src/api/auth/auth.route.ts b/src/api/auth/auth.route.ts index 41db313..b782c4e 100644 --- a/src/api/auth/auth.route.ts +++ b/src/api/auth/auth.route.ts @@ -1,5 +1,5 @@ import Elysia from "elysia"; -import { getUserData, updateUser } from "./auth.controller"; +import { generateToken, getUserData, updateUser, verifyToken } from "./auth.controller"; export const authRoute = new Elysia({ prefix: "/auth", @@ -9,6 +9,11 @@ export const authRoute = new Elysia({ } }) -authRoute.get("/user/:userId", ({ params: { userId } }) => getUserData(userId)); +authRoute.get("/user/:userId", async ({ params: { userId } }) => await getUserData(userId)); + +authRoute.post("/user/update/:userId", async ({ params: { userId }, body }) => await updateUser(userId, body)); + +authRoute.get("/generate-token/:userId", async (context) => await generateToken(context)); + +authRoute.get("/verify-token", async (context) => await verifyToken(context)); -authRoute.post("/user/update/:userId", ({ params: { userId }, body }) => updateUser(userId, body)); \ No newline at end of file diff --git a/src/api/index.ts b/src/api/index.ts index a8e4876..4e41b50 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -3,13 +3,14 @@ import { projectRoutes } from "./project/project.route"; import { uploadRoutes } from "./upload/upload.route"; import { verifyAuth } from "../middlewares/auth.middlewares"; import { authRoute } from "./auth/auth.route"; +import cookie from "@elysiajs/cookie"; export const api = new Elysia({ prefix: "/api", }); // api.derive(verifyAuth); - +api.use(cookie()); api.use(authRoute); api.use(projectRoutes); api.use(uploadRoutes); \ No newline at end of file diff --git a/src/app.ts b/src/app.ts index 36d9477..06247e6 100644 --- a/src/app.ts +++ b/src/app.ts @@ -6,7 +6,10 @@ import cors from "@elysiajs/cors"; import { api } from "./api"; const app = new Elysia() - .use(cors()) + .use(cors({ + origin: "http://localhost:5175", + credentials: true, + })) .use(swagger({ path: "/docs", documentation: { diff --git a/src/config/env.ts b/src/config/env.ts index 0f231a5..8bd4ea4 100644 --- a/src/config/env.ts +++ b/src/config/env.ts @@ -9,4 +9,6 @@ export const ENV = { MINIO_ENDPOINT: process.env.MINIO_ENDPOINT, MINIO_PORT: process.env.MINIO_PORT, CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY, + JWT_ACCESS_TOKEN_SECRET: process.env.JWT_ACCESS_TOKEN_SECRET, + JWT_REFRESH_TOKEN_SECRET: process.env.JWT_REFRESH_TOKEN_SECRET, } \ No newline at end of file diff --git a/src/db/schema.ts b/src/db/schema.ts index bad7cf9..baee876 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -2,8 +2,13 @@ import { json, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core"; export const users = pgTable("users", { id: text("user_id").primaryKey().notNull(), + email: text("email").notNull(), + lastName: text("last_name"), + firstName: text("first_name"), + image: text("image"), paid_status: text("paid_status"), expires_in: text("expires_in"), + refresh_token: text("refresh_token"), }); export const projects = pgTable("projects", { diff --git a/src/helper/auth/auth.helper.ts b/src/helper/auth/auth.helper.ts new file mode 100644 index 0000000..6560f23 --- /dev/null +++ b/src/helper/auth/auth.helper.ts @@ -0,0 +1,51 @@ +import { eq } from "drizzle-orm"; +import { db } from "../../db"; +import { users } from "../../db/schema"; + +type User = { + id: string; + email: string; + lastName: string; + firstName: string; + image: string; +} + +// this will check the user into our local canvas database +export const checkUserInDB = async (id: string) => { + try { + const user = await db.select().from(users).where(eq(users.id, id)); + return { status: 200, found: user?.length > 0 }; + } catch (error: any) { + console.error("Error in checkUserInDB:", error.message || error.toString()); + return { status: 500, message: `An error occurred while checking the user in DB` }; + } +}; + +export const createUser = async (body: User) => { + try { + const { id, email, lastName, firstName, image } = body; + + const [saveUser] = await db.insert(users).values({ id, email, lastName, firstName, image }).returning({ insertedId: users.id }); + + if (!saveUser || !saveUser.insertedId) { + throw new Error("Failed to create user or missing insertedId"); + } + + return { status: 200, message: "User created successfully", data: saveUser.insertedId }; + } catch (error: any) { + console.error("Error in createUser:", error.message || error.toString()); + return { status: 500, message: `An error occurred while creating the user` }; + } +}; + +// this will store the refresh token in the database +export const storeRefreshToken = async (userId: string, refreshToken: string) => { + try { + // store refresh token in db + const storeRToken = await db.update(users).set({ refresh_token: refreshToken }).where(eq(users.id, userId)).returning({ updatedId: users.id }); + return { status: 200, message: "Refresh token stored successfully" }; + } catch (error: any) { + console.error("Error in storeRToken:", error.message || error.toString()); + return { status: 500, message: `An error occurred while storing the refresh token` } + } +}