From 860b9d583e720ba5e3d003e1eaca81faf22e360f Mon Sep 17 00:00:00 2001 From: Puyodead1 Date: Sat, 25 Mar 2023 18:01:56 -0400 Subject: [PATCH] oapi: finish users --- assets/openapi.json | Bin 436484 -> 441299 bytes assets/schemas.json | Bin 15037707 -> 15523974 bytes src/api/routes/applications/#id/bot/index.ts | 4 +- src/api/routes/auth/register.ts | 2 +- src/api/routes/auth/reset.ts | 2 +- .../users/@me/guilds/#guild_id/settings.ts | 36 ++++++++++++++---- src/api/routes/users/@me/mfa/totp/disable.ts | 12 +++++- src/api/routes/users/@me/mfa/totp/enable.ts | 15 +++++++- .../mfa/webauthn/credentials/#key_id/index.ts | 34 +++++++++++------ .../@me/mfa/webauthn/credentials/index.ts | 12 +++++- src/util/schemas/responses/TokenResponse.ts | 11 +++++- src/util/schemas/responses/UserResponse.ts | 11 +----- .../responses/WebAuthnCreateResponse.ts | 4 ++ src/util/schemas/responses/index.ts | 1 + 14 files changed, 107 insertions(+), 37 deletions(-) create mode 100644 src/util/schemas/responses/WebAuthnCreateResponse.ts diff --git a/assets/openapi.json b/assets/openapi.json index 211b84510862b00e71f4f2b2d62a5d2696f30866..c6469fd1c63d809e64228defecbd02675a5e6392 100644 GIT binary patch delta 435 zcmZpGZoy=Qm$K9MyRmUi z|K!XhHC@1z#cs00N<|KsqUi#;jMCE;!kA1aKj>%K{<(;`MRWRu0_ISNrc2z+1{~q3 zNsgr@8F|y??3uGB3p|Shxw&WZf*n$m7x=SI=FQXJZa<%Srtb8DTg*SEFNkB~n11Fs z%Z%+49y6CSPCxLTxpR8$DQ3y(ch554nVwh78b8g0C3}1OdFIE=U@e?*|7_2>&1}fB zJ?aXx9}|)kFa#>MFI>c?$29%GC+3vxQ?4_cse$ATrYnfCd2Da^!pzCqs?XA@&$?Bg cEise@reOl(c7<@Z$y-^HtdxQzkRkNl&+5 z#8@+l8u*uPJZ diff --git a/assets/schemas.json b/assets/schemas.json index ee84a99b961f94573eb03f10ed24416911e7afaa..d427af1baa5ed2326cf5a619f923f0d43c3c74e5 100644 GIT binary patch delta 13153 zcmche`&*M&62~8|F$sYPL=eJFL_|Q4i-=l{h}t656a@iSC_$8q3sk9CTO>%fH zb0~TA1#j==I-XKxRB!ymf)|#YlKFAYaym~HH=XM01rb#F(0DVI-^od&yZ_$fL}fXv zr_+|@M!r;@Txt%{wFCA>R9oBRIR2PV%NHr^sW{cxjPC925z~R+mbg>d_VgfdRk^&e zpvvY?c{Km9lMOL*Fa|RRlSluW3?vz`G=&jMvswQ}rV)EnbFeq%<)F*Dq~r5Q=?fl| zzL*m57+V&j!6lvG?PSOjkoF-Vv=3Q?VAIIUTOxRQ%Q6!kr0BE)MW;9v-TyRgQ$f>a zJsVw7GuS{g*h=s~7v!aU5$UUyKws@NuZL(Z&NwC_!arsQ{A2dfsCpPDv0^$TRyZ^~ z!PP?<$DFv9If84MG~^K)Y&@^OwIH$koFI0e^R?g5K!kx9%=P7SGz7Ot5j)}rc4S62 zdQw#txPz)-W;}XQxSi_(w{vINkLZ%TK$kRU z@E2^iU^LLK^+^~(22s5%zZhTeiGl!JKlwj9q+}Vo35@o0_vJqhauJuAM$@-?mb!` z38VEr0*D!zM?qjD~j(#G#v-3$xDEmybV(H zvcE0+chHu-aS`Ggaf-%L6JabhiQ;V-?CAW~g628C=c|@a{e>Kn1;PDWprb8MxFwTtWweHNN!VN`WJl7Yp3!fL9M|VHXQ# zP;n5?Os#dDO>ckeo!9t}yeoc|il}Ug;K&7yC$9?t5snbvB5Z%caEC3HP;ao-9q?!ULhc0}SmEepJ-Wdrt# z5w>D5Ao!>WT~XzmkD&6+HdkyAWgsEBGQ1tG4CmTS4sGbc$1wC@ht=fJUiap~>)xF! zuxUir@d?N}c7>rkA)7~mviY+pY(@IP7wJBq58dZ?hffa8vAO^ptCjEK(e&FtQD_Q5 zq1m$nuZre4)rX3p`j84SVQ`!j)gK^5wYLoK_`z|WFZ~j+|G^nAT>KS; zi!0GNLeoEk(DX1mr+f4;bdOerVLP4O<0D}A_$cl!$Fiv6?lDl@{W=0$&zY`o;7r%? zcx1n(jKe3kSF6GH>bEV(qNuQqCnSRnCt$Fl2Hk>wr%!_4=~^G;^i3JZoNPLI3O1cQ z{Ty$(zGclE5s9z*3&dBQF~aNja-4+nvyf1JZXJ4a>eT-8aB6?uEOd}oSr1y}U%l|k zAH#fRH17h8=7BZ3B3{;az{_gT;zg}NQBU$k=t=&Y92-Pq3mlz@ET$1;F_#c;`WR$w zS=|I%RyTi+SKu2!BjGJD5`H-v+kPZ`K`VqWXhXj+$6uG7nVPjGYwIVp(5F3;_Ad=Q zNc{KQ2md_}2C=)owtD#b^xQPVCDrUrsoN*MV}V+3ZpByVudgPhWYfzE6Z`RIo?Au7 zV%Br({>FErn*U&{on)f3CYtya_Sa_6uAK=IQWe??RiSNn5EXG#lzg9d$oILj4{!GX z4#ac23Ou*(5w98%24b)uO%Mm}3?USeEa5fC5_Sj?^DKAEW2eziu+!+eHDdU3pyHA1 zP(0FUj#sf5+@Ngu29ynJBhf)@m<#<+yAhAJ21Oo&H^F1@XUqnkK7wd&Pmh;cTP&tl zii>mk6B&pMl-`4Z(!slkxk5k9(@%)ZmTyZ<&ZUJ?O%#;{r#YxyMLx8DsdZzP^ur<(F}=~zYesWs zTH8|PJ##y%3pSC^{@}Frggt;89shWa{&_oi0!Px-CtWkL%8kG-X5%*mt KYt+J6kpDlCM%hCE delta 2296 zcmY*aYfw{H5FRiDh=~v&5h98BKoUh!tVN0<^6&u&6fN=)0kxu1C19uA zxfRD2SF$+vXwb$E25szRPZ&>P0lC#k<1kMS>NJdmP6OAEhEE*eLE^xu42nfM2N3BT z{b{;`J$yLW<0Pea&u(Y%>~;}oAuqAe$VCd302C_WOr05Hf>}u1F&e}juCa`hnN+sB zfwEn6>e+D5d#z*OUaR|DJt8e2kA&1dR%wS6r^bTfl!xItQXd-!>SNnkTvH%%{c#bCI&q3zUu0K3X-mUIyIy$vO?wn()dg5MJq>_%DME zwNt@RJB?3qO1%%H)K4d;G))F6D`$YR()R_$E@d;prR+T!#U;CELCNm-#T2s&{D4(3 zd#;`-%4=%?57p)RLtX9%KGcbj;I(zm7>e~q=f({EtIb{!|eDl$c|sY*8;H;@9yY@&>g+#f`-8Z3l_t`g7D?k zUKJPtRe_Q7nQXWwxQm5m`z?Xleo>d0KAA||v3Mj8FBdKk#|{rR*kSpgw*;%D$rH*l zS)*}Hti2GYrU)b`$R`?td}92V>t_zAn*1TCCdV$NjWA`|?zt4UdoClTneV-c#O@yf zc8^P;b2O3B!sQSxjNdWD%t0zj0I4Xklg=@Mp9B&774G!PpXDaQS?JPn<8|K-CA?e%2`@jsOv^KoIelv(r!QSZ zhxN2~9X#z_KaJwd`x_whe#Q(f1l4?I}p^DEf3 zGdF_bDYH8iR<14Z0gw1b5?hFJuzE6$=g??|L8--|)KsJ$^8nWsfo@ErpCp z%Wn5F$xSL#9IAlg(Bdim!%1OS2?)bVLuuJf0ehe+U~f3ZF}`IG=TYmaDl%H<) z)G=7ld;$c`C#7_&iRQA=zQX|f4!3aW?im_RfuZ5FN`r`e5eYjRHS|`BM)2@!h0GPH z_nrgw-t#gYA|x@i?KYUrXkk%1EG)V}Zl+1eup;X+3-#q+gueVszI0Pf@=&;535DxB zc3P0>X;&dV?OK9`u(>5(2e-sdD+_XS>O*ouP4FKv3^ps=;*dMAIOI=q;f9Hs#=jdh{&(qenRT>i`d_lr>D+0hDQq@wIwZEi zCsuJBaCOLS8=RVS-Md8ZgjJ`l9dT8Ul^gCy31S?>OXg#v(%BuWC2|Q)z3k?QgF?Dy z;k<_pNu{aAQFyLmhHL3cwk>YE>g0o4t`9Q17URd}}g8d)22ZA7$q=!oQR zI3iJ#-;i0U?&Qo9p(tSwL { - const user = await Member.findOneOrFail({ - where: { id: req.user_id, guild_id: req.params.guild_id }, - select: ["settings"], - }); - return res.json(user.settings); -}); +router.get( + "/", + route({ + responses: { + 200: {}, + 404: {}, + }, + }), + async (req: Request, res: Response) => { + const user = await Member.findOneOrFail({ + where: { id: req.user_id, guild_id: req.params.guild_id }, + select: ["settings"], + }); + return res.json(user.settings); + }, +); router.patch( "/", - route({ requestBody: "UserGuildSettingsSchema" }), + route({ + requestBody: "UserGuildSettingsSchema", + responses: { + 200: {}, + 400: { + body: "APIErrorResponse", + }, + 404: { + body: "APIErrorResponse", + }, + }, + }), async (req: Request, res: Response) => { const body = req.body as UserGuildSettingsSchema; diff --git a/src/api/routes/users/@me/mfa/totp/disable.ts b/src/api/routes/users/@me/mfa/totp/disable.ts index bade76c3..362152d7 100644 --- a/src/api/routes/users/@me/mfa/totp/disable.ts +++ b/src/api/routes/users/@me/mfa/totp/disable.ts @@ -31,7 +31,17 @@ const router = Router(); router.post( "/", - route({ requestBody: "TotpDisableSchema" }), + route({ + requestBody: "TotpDisableSchema", + responses: { + 200: { + body: "TokenOnlyResponse", + }, + 400: { + body: "APIErrorResponse", + }, + }, + }), async (req: Request, res: Response) => { const body = req.body as TotpDisableSchema; diff --git a/src/api/routes/users/@me/mfa/totp/enable.ts b/src/api/routes/users/@me/mfa/totp/enable.ts index 87bbaec9..19836e4d 100644 --- a/src/api/routes/users/@me/mfa/totp/enable.ts +++ b/src/api/routes/users/@me/mfa/totp/enable.ts @@ -32,7 +32,20 @@ const router = Router(); router.post( "/", - route({ requestBody: "TotpEnableSchema" }), + route({ + requestBody: "TotpEnableSchema", + responses: { + 200: { + body: "TokenWithBackupCodesResponse", + }, + 400: { + body: "APIErrorResponse", + }, + 404: { + body: "APIErrorResponse", + }, + }, + }), async (req: Request, res: Response) => { const body = req.body as TotpEnableSchema; diff --git a/src/api/routes/users/@me/mfa/webauthn/credentials/#key_id/index.ts b/src/api/routes/users/@me/mfa/webauthn/credentials/#key_id/index.ts index 04aca7e4..9cf42def 100644 --- a/src/api/routes/users/@me/mfa/webauthn/credentials/#key_id/index.ts +++ b/src/api/routes/users/@me/mfa/webauthn/credentials/#key_id/index.ts @@ -21,21 +21,31 @@ import { SecurityKey, User } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router = Router(); -router.delete("/", route({}), async (req: Request, res: Response) => { - const { key_id } = req.params; +router.delete( + "/", + route({ + responses: { + 204: {}, + }, + }), + async (req: Request, res: Response) => { + const { key_id } = req.params; - await SecurityKey.delete({ - id: key_id, - user_id: req.user_id, - }); + await SecurityKey.delete({ + id: key_id, + user_id: req.user_id, + }); - const keys = await SecurityKey.count({ where: { user_id: req.user_id } }); + const keys = await SecurityKey.count({ + where: { user_id: req.user_id }, + }); - // disable webauthn if there are no keys left - if (keys === 0) - await User.update({ id: req.user_id }, { webauthn_enabled: false }); + // disable webauthn if there are no keys left + if (keys === 0) + await User.update({ id: req.user_id }, { webauthn_enabled: false }); - res.sendStatus(204); -}); + res.sendStatus(204); + }, +); export default router; diff --git a/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts b/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts index 46bdfdd0..f383ffb7 100644 --- a/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts +++ b/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts @@ -73,7 +73,17 @@ router.get("/", route({}), async (req: Request, res: Response) => { router.post( "/", - route({ requestBody: "WebAuthnPostSchema" }), + route({ + requestBody: "WebAuthnPostSchema", + responses: { + 200: { + body: "WebAuthnCreateResponse", + }, + 400: { + body: "APIErrorResponse", + }, + }, + }), async (req: Request, res: Response) => { if (!WebAuthn.fido2) { // TODO: I did this for typescript and I can't use ! diff --git a/src/util/schemas/responses/TokenResponse.ts b/src/util/schemas/responses/TokenResponse.ts index c811632f..7e93055a 100644 --- a/src/util/schemas/responses/TokenResponse.ts +++ b/src/util/schemas/responses/TokenResponse.ts @@ -1,6 +1,15 @@ -import { UserSettings } from "../../entities"; +import { BackupCode, UserSettings } from "../../entities"; export interface TokenResponse { token: string; settings: UserSettings; } + +export interface TokenOnlyResponse { + token: string; +} + +export interface TokenWithBackupCodesResponse { + token: string; + backup_codes: BackupCode[]; +} diff --git a/src/util/schemas/responses/UserResponse.ts b/src/util/schemas/responses/UserResponse.ts index 21c30cd5..95f73649 100644 --- a/src/util/schemas/responses/UserResponse.ts +++ b/src/util/schemas/responses/UserResponse.ts @@ -1,5 +1,5 @@ import { DmChannelDTO } from "../../dtos"; -import { Guild, PrivateUser, PublicUser, User } from "../../entities"; +import { BackupCode, Guild, PrivateUser, PublicUser } from "../../entities"; export type PublicUserResponse = PublicUser; export type PrivateUserResponse = PrivateUser; @@ -12,11 +12,4 @@ export type UserGuildsResponse = Guild[]; export type UserChannelsResponse = DmChannelDTO[]; -export interface UserBackupCodesResponse { - expired: unknown; - user: User; - code: string; - consumed: boolean; - id: string; -} -[]; +export type UserBackupCodesResponse = BackupCode[]; diff --git a/src/util/schemas/responses/WebAuthnCreateResponse.ts b/src/util/schemas/responses/WebAuthnCreateResponse.ts new file mode 100644 index 00000000..9aa9e206 --- /dev/null +++ b/src/util/schemas/responses/WebAuthnCreateResponse.ts @@ -0,0 +1,4 @@ +export interface WebAuthnCreateResponse { + name: string; + id: string; +} diff --git a/src/util/schemas/responses/index.ts b/src/util/schemas/responses/index.ts index 1f0e2aed..e75ab382 100644 --- a/src/util/schemas/responses/index.ts +++ b/src/util/schemas/responses/index.ts @@ -44,4 +44,5 @@ export * from "./UserProfileResponse"; export * from "./UserRelationshipsResponse"; export * from "./UserRelationsResponse"; export * from "./UserResponse"; +export * from "./WebAuthnCreateResponse"; export * from "./WebhookCreateResponse";