Skip to content

Commit ea6e668

Browse files
CopilotTechQuery
andauthored
Fix signIn page: auth chain only on code param, flatten JSX, function-style translation, revert UserBar
Agent-Logs-Url: https://github.com/FreeCodeCamp-Chengdu/HOP/sessions/8c9b2f6e-88e2-42e9-b04e-34847c85dda8 Co-authored-by: TechQuery <19969570+TechQuery@users.noreply.github.com>
1 parent ab2b4a6 commit ea6e668

5 files changed

Lines changed: 38 additions & 20 deletions

File tree

components/User/UserBar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const UserBar = observer(() => {
3838
</Dropdown.Menu>
3939
</Dropdown>
4040
) : (
41-
<Button variant="outline-light" href="/user/signIn">
41+
<Button variant="outline-light" href="/user/me">
4242
{t('sign_in')}
4343
</Button>
4444
)}

pages/user/signIn.tsx

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { faGithub } from '@fortawesome/free-brands-svg-icons';
22
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3+
import { verify } from 'jsonwebtoken';
34
import { observer } from 'mobx-react';
45
import { compose } from 'next-ssr-middleware';
56
import { FC, useContext } from 'react';
67
import { Button, Container } from 'react-bootstrap';
78

89
import { PageHead } from '../../components/layout/PageHead';
10+
import { JWT_SECRET } from '../../configuration';
911
import { I18nContext } from '../../models/Base/Translation';
1012
import { GITHUB_OAUTH_SCOPES, githubSigner, jwtSigner } from '../api/core';
1113

@@ -19,12 +21,30 @@ export const getServerSideProps = compose<SignInPageProps>(
1921
const { query, req } = context;
2022
const callback = (query.callback as string) || '/';
2123

22-
const result = await next();
24+
// If there is a `code` param, this is the OAuth callback — run the auth
25+
// middleware chain (githubSigner exchanges the code for a token cookie,
26+
// jwtSigner then signs a JWT and returns jwtPayload in props).
27+
if (query.code) {
28+
const result = await next();
2329

24-
if ('props' in result && (result.props as any).jwtPayload) {
30+
if ('props' in result && (result.props as any).jwtPayload)
31+
return { redirect: { destination: callback, permanent: false } };
32+
33+
return result;
34+
}
35+
36+
// If the user is already logged in, skip the sign-in page.
37+
const { JWT: jwtCookie = '' } = req.cookies;
38+
39+
try {
40+
verify(jwtCookie, JWT_SECRET!);
2541
return { redirect: { destination: callback, permanent: false } };
42+
} catch {
43+
// Not logged in — fall through to render the sign-in page.
2644
}
2745

46+
// Build the GitHub OAuth URL pointing back to this page so the callback
47+
// lands here and is processed by the middleware chain above.
2848
const proto =
2949
(req.headers['x-forwarded-proto'] as string) ||
3050
((req as any).socket?.encrypted ? 'https' : 'http');
@@ -42,21 +62,19 @@ const SignInPage: FC<SignInPageProps> = observer(({ githubOAuthURL }) => {
4262
const { t } = useContext(I18nContext);
4363

4464
return (
45-
<>
65+
<Container className="d-flex flex-column align-items-center justify-content-center min-vh-100 gap-3">
4666
<PageHead title={t('sign_in')} />
47-
<Container className="d-flex flex-column align-items-center justify-content-center min-vh-100 gap-3">
48-
<h1>{t('sign_in')}</h1>
49-
<Button
50-
as="a"
51-
href={githubOAuthURL}
52-
size="lg"
53-
className="d-flex align-items-center gap-2"
54-
>
55-
<FontAwesomeIcon icon={faGithub} />
56-
{t('sign_in_with_github')}
57-
</Button>
58-
</Container>
59-
</>
67+
<h1>{t('sign_in')}</h1>
68+
<Button
69+
as="a"
70+
href={githubOAuthURL}
71+
size="lg"
72+
className="d-flex align-items-center gap-2"
73+
>
74+
<FontAwesomeIcon icon={faGithub} />
75+
{t('sign_in_with')('GitHub')}
76+
</Button>
77+
</Container>
6078
);
6179
});
6280

translation/en-US.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,6 @@ export default {
359359
preview_questionnaire: 'Preview the questionnaire',
360360
confirm_to_delete_questionnaire: 'Confirm to delete the questionnaire?',
361361
fill_default_questions: 'Fill with default questions',
362-
sign_in_with_github: 'Sign in with GitHub',
362+
sign_in_with: (platform: string) => `Sign in with ${platform}`,
363363
for_example: (example: string) => 'E.g., ' + example,
364364
} as const;

translation/zh-CN.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,6 @@ export default {
354354
preview_questionnaire: '问卷预览',
355355
confirm_to_delete_questionnaire: '确认删除该问卷?',
356356
fill_default_questions: '填入默认问题',
357-
sign_in_with_github: '用 GitHub 账号登录',
357+
sign_in_with: (platform: string) => `用 ${platform} 账号登录`,
358358
for_example: (example: string) => '例如:' + example,
359359
} as const;

translation/zh-TW.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,6 @@ export default {
354354
preview_questionnaire: '預覽問卷',
355355
confirm_to_delete_questionnaire: '確定刪除該問卷?',
356356
fill_default_questions: '填入預設問題',
357-
sign_in_with_github: '用 GitHub 帳號登錄',
357+
sign_in_with: (platform: string) => `用 ${platform} 帳號登錄`,
358358
for_example: (example: string) => '例如:' + example,
359359
} as const;

0 commit comments

Comments
 (0)