@@ -834,129 +834,159 @@ app.get("/auth/callback", async (req, res) => {
834
834
res . redirect ( `${ WEBSITE_URL } /dashboard` ) ;
835
835
} ) ;
836
836
837
- app . get (
838
- "/auth/user" ,
837
+ const userRouter = express . Router ( ) ;
838
+
839
+ userRouter . use (
839
840
cors ( {
840
841
origin : [ "http://localhost:56413" , "https://chatr.fun" ] ,
841
842
credentials : true ,
842
- } ) ,
843
- async ( req , res ) => {
844
- const user = await getUserFromRequest ( req ) ;
843
+ } )
844
+ ) ;
845
+
846
+ userRouter . get ( "/" , async ( req , res ) => {
847
+ const user = await getUserFromRequest ( req ) ;
848
+
849
+ if ( ! user ) return res . status ( 401 ) . json ( { message : "Unauthorized" } ) ;
845
850
846
- if ( ! user ) return res . status ( 401 ) . json ( { message : "Unauthorized" } ) ;
851
+ res . json ( {
852
+ ...user ,
853
+ access_token : undefined ,
854
+ refresh_token : undefined ,
855
+ expires_at : undefined ,
856
+ } ) ;
857
+ } ) ;
847
858
848
- res . json ( user ) ;
859
+ userRouter . delete ( "/" , async ( req , res ) => {
860
+ if ( ! ( await getUserFromRequest ( req ) ) ) {
861
+ return res . status ( 401 ) . json ( { message : "Unauthorized" } ) ;
849
862
}
850
- ) ;
851
863
852
- app . post (
853
- "/auth/logout" ,
854
- cors ( {
855
- origin : [ "http://localhost:56413" , "https://chatr.fun" ] ,
856
- credentials : true ,
857
- } ) ,
858
- async ( req , res ) => {
859
- if ( ! ( await getUserFromRequest ( req ) ) ) {
860
- return res . status ( 401 ) . json ( { message : "Unauthorized" } ) ;
864
+ res . clearCookie ( "token" ) ;
865
+
866
+ return res . sendStatus ( 200 ) ;
867
+ } ) ;
868
+
869
+ app . use ( "/user/me" , userRouter ) ;
870
+
871
+ app . get ( "/auth/user/guilds" , async ( req , res ) => {
872
+ const user = await getUserFromRequest ( req ) ;
873
+
874
+ if ( ! user ) return res . status ( 401 ) . json ( { message : "Unauthorized" } ) ;
875
+
876
+ const botGuildsResponse = await fetch (
877
+ "https://discord.com/api/users/@me/guilds" ,
878
+ {
879
+ headers : {
880
+ Authorization : `Bot ${ process . env . DISCORD_TOKEN_DEV ?? process . env . DISCORD_TOKEN } ` ,
881
+ } ,
882
+ }
883
+ ) ;
884
+ const botGuilds = await botGuildsResponse . json ( ) ;
885
+
886
+ const [ err , accessToken ] = await getAccessToken ( user ) ;
887
+
888
+ if ( err ) return res . status ( 500 ) . json ( { message : err } ) ;
889
+
890
+ const userGuildsResponse = await fetch (
891
+ "https://discord.com/api/users/@me/guilds" ,
892
+ {
893
+ headers : {
894
+ Authorization : `Bearer ${ accessToken } ` ,
895
+ } ,
861
896
}
897
+ ) ;
898
+ const userGuilds = await userGuildsResponse . json ( ) ;
862
899
863
- res . clearCookie ( "token" ) ;
900
+ const filteredGuilds = userGuilds . filter (
901
+ ( guild : any ) => guild . owner || ( guild . permissions & 0x20 ) === 0x20
902
+ ) ;
864
903
865
- return res . sendStatus ( 200 ) ;
866
- }
867
- ) ;
904
+ res . json (
905
+ filteredGuilds
906
+ . map ( ( guild : any ) => ( {
907
+ ...guild ,
908
+ icon : guild . icon
909
+ ? `https://cdn.discordapp.com/icons/${ guild . id } /${ guild . icon } .webp`
910
+ : null ,
911
+ botIsInGuild : botGuilds . some (
912
+ ( botGuild : any ) => botGuild . id === guild . id
913
+ ) ,
914
+ } ) )
915
+ . sort ( ( a : any , b : any ) => {
916
+ if ( a . botIsInGuild === b . botIsInGuild ) {
917
+ return a . name . localeCompare ( b . name ) ;
918
+ }
868
919
869
- app . get (
870
- "/auth/user/guilds" ,
920
+ return Number ( b . botIsInGuild ) - Number ( a . botIsInGuild ) ;
921
+ } )
922
+ ) ;
923
+ } ) ;
924
+
925
+ app . options (
926
+ "/auth/update-guild" ,
927
+ cors ( {
928
+ origin : [ "http://localhost:56413" , "https://chatr.fun" ] ,
929
+ credentials : true ,
930
+ } )
931
+ ) ;
932
+ app . put (
933
+ "/auth/update-guild" ,
871
934
cors ( {
872
935
origin : [ "http://localhost:56413" , "https://chatr.fun" ] ,
873
936
credentials : true ,
874
937
} ) ,
875
938
async ( req , res ) => {
876
- const user = await getUserFromRequest ( req ) ;
877
-
878
- if ( ! user ) return res . status ( 401 ) . json ( { message : "Unauthorized" } ) ;
939
+ if ( ! ( await getUserFromRequest ( req ) ) )
940
+ return res . status ( 401 ) . json ( { message : "Unauthorized" } ) ;
879
941
880
- let accessToken = user . access_token ;
942
+ const body = req . body ;
943
+ const { guild } = req . body ;
881
944
882
- if ( new Date ( ) . getTime ( ) > user . expires_at . getTime ( ) ) {
883
- const body = new URLSearchParams ( ) ;
945
+ if ( ! guild ) return res . status ( 400 ) . json ( { message : "Illegal request" } ) ;
884
946
885
- body . append ( "client_id" , process . env . DISCORD_CLIENT_ID ! ) ;
886
- body . append ( "client_secret" , process . env . DISCORD_CLIENT_SECRET ! ) ;
887
- body . append ( "grant_type" , "refresh_token" ) ;
888
- body . append ( "refresh_token" , user . refresh_token ) ;
889
- body . append ( "scope" , "identify guilds" ) ;
947
+ if ( body . cooldown ) {
948
+ await setCooldown ( guild , body . cooldown ) ;
949
+ }
890
950
891
- const tokenResponse = await fetch (
892
- "https://discord.com/api/oauth2/token" ,
893
- {
894
- method : "POST" ,
895
- body,
896
- headers : {
897
- "Content-Type" : "application/x-www-form-urlencoded" ,
898
- } ,
899
- }
900
- ) ;
951
+ if ( body . updates . enabled === true ) {
952
+ await enableUpdates ( guild ) ;
953
+ } else if ( body . updates . enabled === false ) {
954
+ await disableUpdates ( guild ) ;
955
+ }
901
956
902
- if ( tokenResponse . status !== 200 ) {
903
- console . error ( "Error fetching token:" , tokenResponse ) ;
957
+ if ( body . updates . channel ) {
958
+ await setUpdatesChannel ( guild , body . updates . channel ) ;
959
+ }
904
960
905
- return res
906
- . status ( 500 )
907
- . json ( { message : "Internal server error" } ) ;
908
- }
961
+ return res . sendStatus ( 204 ) ;
962
+ }
963
+ ) ;
909
964
910
- const tokenData = await tokenResponse . json ( ) ;
965
+ // TODO: fetch from the bot itself using discord.js
966
+ // (would allow us to do permission filtering)
967
+ app . get ( "/channels/:guild" , authMiddleware , async ( req , res ) => {
968
+ const { guild } = req . params ;
911
969
912
- accessToken = tokenData . access_token ;
970
+ const channelsResponse = await fetch (
971
+ `https://discord.com/api/v10/guilds/${ guild } /channels` ,
972
+ {
973
+ headers : {
974
+ Authorization : `Bot ${ process . env . DISCORD_TOKEN_DEV ?? process . env . DISCORD_TOKEN } ` ,
975
+ } ,
913
976
}
977
+ ) ;
978
+ const channelsData = await channelsResponse . json ( ) ;
914
979
915
- const botGuildsResponse = await fetch (
916
- `https://discord.com/api/users/@me/guilds` ,
917
- {
918
- headers : {
919
- Authorization : `Bot ${ process . env . DISCORD_TOKEN_DEV ?? process . env . DISCORD_TOKEN } ` ,
920
- } ,
921
- }
922
- ) ;
923
- const botGuilds = await botGuildsResponse . json ( ) ;
924
-
925
- const userGuildsResponse = await fetch (
926
- `https://discord.com/api/users/@me/guilds` ,
927
- {
928
- headers : {
929
- Authorization : `Bearer ${ accessToken } ` ,
930
- } ,
931
- }
932
- ) ;
933
- const userGuilds = await userGuildsResponse . json ( ) ;
980
+ if ( channelsData . code === 50007 ) {
981
+ return res . status ( 404 ) . json ( { message : "Guild not found" } ) ;
982
+ }
934
983
935
- const filteredGuilds = userGuilds . filter (
936
- ( guild : any ) => guild . owner || ( guild . permissions & 0x20 ) === 0x20
937
- ) ;
984
+ const channels = channelsData
985
+ . filter ( ( channel : any ) => channel . type === 0 )
986
+ . sort ( ( a : any , b : any ) => a . position - b . position ) ;
938
987
939
- res . json (
940
- filteredGuilds
941
- . map ( ( guild : any ) => ( {
942
- ...guild ,
943
- icon : guild . icon
944
- ? `https://cdn.discordapp.com/icons/${ guild . id } /${ guild . icon } .webp`
945
- : null ,
946
- botIsInGuild : botGuilds . some (
947
- ( botGuild : any ) => botGuild . id === guild . id
948
- ) ,
949
- } ) )
950
- . sort ( ( a : any , b : any ) => {
951
- if ( a . botIsInGuild === b . botIsInGuild ) {
952
- return a . name . localeCompare ( b . name ) ;
953
- }
954
-
955
- return Number ( b . botIsInGuild ) - Number ( a . botIsInGuild ) ;
956
- } )
957
- ) ;
958
- }
959
- ) ;
988
+ res . json ( channels ) ;
989
+ } ) ;
960
990
961
991
app . get ( "/invite" , ( req , res ) => {
962
992
const guildId = req . query . guild_id ;
@@ -1084,6 +1114,45 @@ async function getUserFromRequest(req: Request): Promise<OAuthUser | null> {
1084
1114
1085
1115
return user ;
1086
1116
}
1117
+
1118
+ async function getAccessToken (
1119
+ user : OAuthUser
1120
+ ) : Promise < [ string , null ] | [ null , string ] > {
1121
+ let accessToken = user . access_token ;
1122
+
1123
+ if ( new Date ( ) . getTime ( ) > user . expires_at . getTime ( ) ) {
1124
+ const body = new URLSearchParams ( ) ;
1125
+
1126
+ body . append ( "client_id" , process . env . DISCORD_CLIENT_ID ! ) ;
1127
+ body . append ( "client_secret" , process . env . DISCORD_CLIENT_SECRET ! ) ;
1128
+ body . append ( "grant_type" , "refresh_token" ) ;
1129
+ body . append ( "refresh_token" , user . refresh_token ) ;
1130
+ body . append ( "scope" , "identify guilds" ) ;
1131
+
1132
+ const tokenResponse = await fetch (
1133
+ "https://discord.com/api/oauth2/token" ,
1134
+ {
1135
+ method : "POST" ,
1136
+ body,
1137
+ headers : {
1138
+ "Content-Type" : "application/x-www-form-urlencoded" ,
1139
+ } ,
1140
+ }
1141
+ ) ;
1142
+
1143
+ if ( tokenResponse . status !== 200 ) {
1144
+ console . error ( "Error fetching token:" , tokenResponse ) ;
1145
+
1146
+ return [ "Internal server error" , null ] ;
1147
+ }
1148
+
1149
+ const tokenData = await tokenResponse . json ( ) ;
1150
+
1151
+ accessToken = tokenData . access_token ;
1152
+ }
1153
+
1154
+ return [ null , accessToken ] ;
1155
+ }
1087
1156
//#endregion
1088
1157
1089
1158
// TODO: actually implement this in a real way
0 commit comments