Skip to content

Commit b702f56

Browse files
ajout de permissions pour les messages privés Discord (https://discord.c
1 parent 151388d commit b702f56

File tree

2 files changed

+65
-27
lines changed

2 files changed

+65
-27
lines changed

src/app/(app)/profile/page.tsx

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ import { Label } from '@/components/ui/label';
1212
import { useForm } from 'react-hook-form';
1313
import { zodResolver } from '@hookform/resolvers/zod';
1414
import * as z from 'zod';
15-
import { useEffect, useState, useActionState, startTransition } from 'react';
15+
import { useEffect, useState, useActionState, startTransition, useCallback } from 'react';
1616
import { useToast } from '@/hooks/use-toast';
1717
import * as authService from '@/lib/authService';
1818
import { fetchUserGithubOAuthTokenAction, disconnectGithubAction, fetchGithubUserDetailsAction, fetchDiscordUserDetailsAction, disconnectDiscordAction } from '@/app/(app)/projects/[id]/actions';
19-
import { useRouter } from 'next/navigation';
19+
import { useRouter, useSearchParams } from 'next/navigation';
2020
import Link from 'next/link';
2121
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
2222

@@ -49,6 +49,7 @@ type AvatarSource = 'flowup' | 'github' | 'discord';
4949
export default function ProfilePage() {
5050
const { user, isLoading: authLoading, refreshUser } = useAuth();
5151
const router = useRouter();
52+
const searchParams = useSearchParams();
5253
const [isEditing, setIsEditing] = useState(false);
5354
const [isSubmitting, setIsSubmitting] = useState(false);
5455
const { toast } = useToast();
@@ -75,6 +76,28 @@ export default function ProfilePage() {
7576
},
7677
});
7778

79+
const loadExternalData = useCallback(async () => {
80+
if (user) {
81+
setIsLoadingGithub(true);
82+
setIsLoadingDiscord(true);
83+
84+
const tokenData = await fetchUserGithubOAuthTokenAction();
85+
if (tokenData?.accessToken) {
86+
setGithubToken(tokenData.accessToken);
87+
const userDetails = await fetchGithubUserDetailsAction();
88+
setGithubUserDetails(userDetails);
89+
} else {
90+
setGithubToken(null);
91+
setGithubUserDetails(null);
92+
}
93+
setIsLoadingGithub(false);
94+
95+
const discordDetails = await fetchDiscordUserDetailsAction();
96+
setDiscordUserDetails(discordDetails);
97+
setIsLoadingDiscord(false);
98+
}
99+
}, [user]);
100+
78101
useEffect(() => {
79102
if (user) {
80103
form.reset({
@@ -86,29 +109,44 @@ export default function ProfilePage() {
86109
}, [user, form]);
87110

88111
useEffect(() => {
89-
async function loadExternalData() {
90-
if (user) {
91-
setIsLoadingGithub(true);
92-
setIsLoadingDiscord(true);
93-
94-
const tokenData = await fetchUserGithubOAuthTokenAction();
95-
if (tokenData?.accessToken) {
96-
setGithubToken(tokenData.accessToken);
97-
const userDetails = await fetchGithubUserDetailsAction();
98-
setGithubUserDetails(userDetails);
99-
} else {
100-
setGithubToken(null);
101-
setGithubUserDetails(null);
102-
}
103-
setIsLoadingGithub(false);
104-
105-
const discordDetails = await fetchDiscordUserDetailsAction();
106-
setDiscordUserDetails(discordDetails);
107-
setIsLoadingDiscord(false);
108-
}
112+
if (!authLoading) {
113+
loadExternalData();
109114
}
110-
if (!authLoading) loadExternalData();
111-
}, [user, authLoading]);
115+
}, [authLoading, loadExternalData]);
116+
117+
useEffect(() => {
118+
const githubStatus = searchParams.get('oauth_status');
119+
const discordStatus = searchParams.get('discord_oauth_status');
120+
const authError = searchParams.get('error');
121+
const errorMessage = searchParams.get('message');
122+
let urlModified = false;
123+
const newUrl = new URL(window.location.href);
124+
125+
if (githubStatus === 'success') {
126+
toast({ title: "GitHub Connected!", description: "Your GitHub account has been successfully linked." });
127+
loadExternalData();
128+
newUrl.searchParams.delete('oauth_status');
129+
urlModified = true;
130+
}
131+
132+
if (discordStatus === 'success') {
133+
toast({ title: "Discord Connected!", description: "Your Discord account has been successfully linked." });
134+
loadExternalData();
135+
newUrl.searchParams.delete('discord_oauth_status');
136+
urlModified = true;
137+
}
138+
139+
if (authError) {
140+
toast({ variant: 'destructive', title: "Connection Error", description: errorMessage || authError });
141+
newUrl.searchParams.delete('error');
142+
newUrl.searchParams.delete('message');
143+
urlModified = true;
144+
}
145+
146+
if (urlModified) {
147+
router.replace(newUrl.toString(), { scroll: false });
148+
}
149+
}, [searchParams, router, toast, loadExternalData]);
112150

113151
useEffect(() => {
114152
if (user && !isLoadingGithub && !isLoadingDiscord) {
@@ -444,5 +482,3 @@ export default function ProfilePage() {
444482
</div>
445483
);
446484
}
447-
448-

src/app/api/auth/discord/oauth/login/route.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ export async function GET(request: NextRequest) {
3030
discordAuthUrl.searchParams.append('client_id', DISCORD_CLIENT_ID);
3131
discordAuthUrl.searchParams.append('redirect_uri', `${NEXT_PUBLIC_APP_URL}/api/auth/discord/oauth/callback`);
3232
discordAuthUrl.searchParams.append('response_type', 'code');
33-
discordAuthUrl.searchParams.append('scope', 'identify email');
33+
// Requesting 'bot' scope is necessary to enable bot interactions, like sending DMs to the user later.
34+
// This also requires the app to be configured as a bot in the Discord Developer Portal.
35+
discordAuthUrl.searchParams.append('scope', 'identify email bot');
3436
discordAuthUrl.searchParams.append('state', state);
3537

3638
console.log('[Discord OAuth Login] Redirecting to Discord:', discordAuthUrl.toString());

0 commit comments

Comments
 (0)