Skip to content

Commit e96b94e

Browse files
committed
style: reformat codebase
1 parent 81bfa1c commit e96b94e

File tree

12 files changed

+99
-115
lines changed

12 files changed

+99
-115
lines changed

app/(admin)/(user-management)/groups/[id]/_components/audit-info-card.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ function CardMain({ id }: { id: string }) {
2626
<li className="flex items-center gap-2">
2727
<Clock className="h-4 w-4 text-muted-foreground" />
2828
<span>
29-
建立時間:{new Date(data.group.createdAt).toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' })}
29+
建立時間:{new Date(data.group.createdAt).toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}
3030
</span>
3131
</li>
3232
<li className="flex items-center gap-2">
3333
<Clock className="h-4 w-4 text-muted-foreground" />
3434
<span>
35-
更新時間:{new Date(data.group.updatedAt).toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' })}
35+
更新時間:{new Date(data.group.updatedAt).toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}
3636
</span>
3737
</li>
3838
</ul>

app/(admin)/(user-management)/users/[id]/_components/audit-info.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ function CardMain({ id }: { id: string }) {
2626
<li className="flex items-center gap-2">
2727
<Clock className="h-4 w-4 text-muted-foreground" />
2828
<span>
29-
建立時間:{new Date(data.user.createdAt).toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' })}
29+
建立時間:{new Date(data.user.createdAt).toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}
3030
</span>
3131
</li>
3232
<li className="flex items-center gap-2">
3333
<Clock className="h-4 w-4 text-muted-foreground" />
3434
<span>
35-
更新時間:{new Date(data.user.updatedAt).toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' })}
35+
更新時間:{new Date(data.user.updatedAt).toLocaleString("zh-TW", { timeZone: "Asia/Taipei" })}
3636
</span>
3737
</li>
3838
</ul>

app/api/auth/callback/route.ts

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
1+
import { clearOAuthState, exchangeCodeForToken, getOAuthState, OAUTH_CONFIG, setAuthToken } from "@/lib/auth";
12
import { NextRequest, NextResponse } from "next/server";
2-
import {
3-
clearOAuthState,
4-
exchangeCodeForToken,
5-
getOAuthState,
6-
OAUTH_CONFIG,
7-
setAuthToken,
8-
} from "@/lib/auth";
93

104
/**
115
* OAuth 2.0 Authorization Code Flow Callback Handler
12-
*
6+
*
137
* This endpoint handles the callback from the OAuth authorization server
148
* according to RFC 6749 and RFC 7636 (PKCE).
15-
*
9+
*
1610
* Expected query parameters:
1711
* - code: Authorization code from the OAuth server
1812
* - state: State parameter for CSRF protection
@@ -29,49 +23,49 @@ export async function GET(request: NextRequest) {
2923
// Handle OAuth errors
3024
if (error) {
3125
console.error("OAuth authorization error:", error, errorDescription);
32-
26+
3327
const errorUrl = new URL("/login", request.url);
3428
errorUrl.searchParams.set("error", error);
3529
if (errorDescription) {
3630
errorUrl.searchParams.set("error_description", errorDescription);
3731
}
38-
32+
3933
return NextResponse.redirect(errorUrl);
4034
}
4135

4236
// Validate required parameters
4337
if (!code || !state) {
4438
console.error("Missing required parameters in OAuth callback");
45-
39+
4640
const errorUrl = new URL("/login", request.url);
4741
errorUrl.searchParams.set("error", "invalid_request");
4842
errorUrl.searchParams.set("error_description", "Missing required parameters");
49-
43+
5044
return NextResponse.redirect(errorUrl);
5145
}
5246

5347
try {
5448
// Retrieve and validate stored OAuth state
5549
const { state: storedState, codeVerifier } = await getOAuthState();
56-
50+
5751
if (!storedState || !codeVerifier) {
5852
console.error("Missing OAuth state or code verifier");
59-
53+
6054
const errorUrl = new URL("/login", request.url);
6155
errorUrl.searchParams.set("error", "invalid_request");
6256
errorUrl.searchParams.set("error_description", "OAuth state not found");
63-
57+
6458
return NextResponse.redirect(errorUrl);
6559
}
6660

6761
// Validate state parameter (CSRF protection)
6862
if (state !== storedState) {
6963
console.error("OAuth state mismatch", { state, storedState });
70-
64+
7165
const errorUrl = new URL("/login", request.url);
7266
errorUrl.searchParams.set("error", "invalid_request");
7367
errorUrl.searchParams.set("error_description", "Invalid state parameter");
74-
68+
7569
return NextResponse.redirect(errorUrl);
7670
}
7771

@@ -81,9 +75,9 @@ export async function GET(request: NextRequest) {
8175

8276
// Store the access token in encrypted session
8377
await setAuthToken(
84-
tokenResponse.access_token,
85-
tokenResponse.token_type,
86-
tokenResponse.expires_in
78+
tokenResponse.access_token,
79+
tokenResponse.token_type,
80+
tokenResponse.expires_in,
8781
);
8882

8983
// Clear OAuth state cookies
@@ -92,14 +86,13 @@ export async function GET(request: NextRequest) {
9286
// Redirect to the main application
9387
const successUrl = new URL("/", request.url);
9488
return NextResponse.redirect(successUrl);
95-
9689
} catch (error) {
9790
console.error("Token exchange failed:", error);
98-
91+
9992
const errorUrl = new URL("/login", request.url);
10093
errorUrl.searchParams.set("error", "server_error");
10194
errorUrl.searchParams.set("error_description", "Failed to exchange authorization code");
102-
95+
10396
return NextResponse.redirect(errorUrl);
10497
}
10598
}

app/api/auth/login/route.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
1-
import { NextRequest, NextResponse } from "next/server";
2-
import {
3-
buildAuthorizeUrl,
4-
generateCodeVerifier,
5-
generateState,
6-
OAUTH_CONFIG,
7-
setOAuthState,
8-
} from "@/lib/auth";
1+
import { buildAuthorizeUrl, generateCodeVerifier, generateState, OAUTH_CONFIG, setOAuthState } from "@/lib/auth";
92
import { redirectIfAuthenticated } from "@/lib/auth.rsc";
3+
import { NextRequest, NextResponse } from "next/server";
104

115
/**
126
* OAuth 2.0 Authorization Code Flow with PKCE - Login Initiation
13-
*
7+
*
148
* This endpoint initiates the OAuth 2.0 authorization flow according to
159
* RFC 6749 and RFC 7636 (PKCE for OAuth Public Clients).
16-
*
10+
*
1711
* The flow follows these steps:
1812
* 1. Generate PKCE code verifier and challenge
1913
* 2. Generate state parameter for CSRF protection
@@ -40,14 +34,13 @@ export async function GET(request: NextRequest) {
4034

4135
// Redirect to authorization server
4236
return NextResponse.redirect(authorizeUrl);
43-
4437
} catch (error) {
4538
console.error("Login initiation failed:", error);
46-
39+
4740
const errorUrl = new URL("/login", request.url);
4841
errorUrl.searchParams.set("error", "server_error");
4942
errorUrl.searchParams.set("error_description", "Failed to initiate login");
50-
43+
5144
return NextResponse.redirect(errorUrl);
5245
}
5346
}

app/api/auth/logout/route.ts

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
1+
import { clearAuthToken, getAuthToken, revokeToken } from "@/lib/auth";
12
import { NextRequest, NextResponse } from "next/server";
2-
import {
3-
clearAuthToken,
4-
getAuthToken,
5-
revokeToken,
6-
} from "@/lib/auth";
73

84
/**
95
* OAuth 2.0 Token Revocation - Logout Handler
10-
*
6+
*
117
* This endpoint handles user logout according to RFC 7009 (OAuth 2.0 Token Revocation).
12-
*
8+
*
139
* The logout process:
1410
* 1. Retrieve the access token from HttpOnly cookie
1511
* 2. Revoke the token at the authorization server
1612
* 3. Clear the authentication cookie
1713
* 4. Redirect to login page
1814
*/
19-
export async function POST(_request: NextRequest) {
15+
export async function POST() {
2016
try {
2117
// Get the current access token
2218
const token = await getAuthToken();
@@ -37,23 +33,22 @@ export async function POST(_request: NextRequest) {
3733

3834
// Return success response
3935
return NextResponse.json({ success: true }, { status: 200 });
40-
4136
} catch (error) {
4237
console.error("Logout failed:", error);
43-
38+
4439
// Even if logout fails, clear the local cookie
4540
try {
4641
await clearAuthToken();
4742
} catch (clearError) {
4843
console.error("Failed to clear auth cookie:", clearError);
4944
}
50-
45+
5146
return NextResponse.json(
52-
{
53-
error: "server_error",
54-
error_description: "Logout failed, but local session cleared"
47+
{
48+
error: "server_error",
49+
error_description: "Logout failed, but local session cleared",
5550
},
56-
{ status: 500 }
51+
{ status: 500 },
5752
);
5853
}
5954
}
@@ -81,22 +76,21 @@ export async function GET(request: NextRequest) {
8176
// Redirect to login page
8277
const loginUrl = new URL("/login", request.url);
8378
loginUrl.searchParams.set("message", "logged_out");
84-
85-
return NextResponse.redirect(loginUrl);
8679

80+
return NextResponse.redirect(loginUrl);
8781
} catch (error) {
8882
console.error("Logout failed:", error);
89-
83+
9084
// Even if logout fails, clear the local cookie and redirect
9185
try {
9286
await clearAuthToken();
9387
} catch (clearError) {
9488
console.error("Failed to clear auth cookie:", clearError);
9589
}
96-
90+
9791
const loginUrl = new URL("/login", request.url);
9892
loginUrl.searchParams.set("error", "logout_failed");
99-
93+
10094
return NextResponse.redirect(loginUrl);
10195
}
10296
}

app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import type { Metadata } from "next";
22
import { Geist, Geist_Mono } from "next/font/google";
33
import "./globals.css";
44
import { Toaster } from "@/components/ui/sonner";
5+
import { getAuthToken } from "@/lib/auth";
56
import { ApolloWrapper } from "@/providers/use-apollo";
67
import { PreloadResources } from "./preload-resources";
7-
import { getAuthToken } from "@/lib/auth";
88

99
const geistSans = Geist({
1010
variable: "--font-geist-sans",

app/login/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default async function LoginPage({ searchParams }: LoginPageProps) {
4141
</div>
4242
Database Playground
4343
</Link>
44-
<LoginForm
44+
<LoginForm
4545
error={params.error}
4646
errorDescription={params.error_description}
4747
message={params.message}

components/login-form.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import { Alert, AlertDescription } from "@/components/ui/alert";
12
import { Button } from "@/components/ui/button";
23
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
3-
import { Alert, AlertDescription } from "@/components/ui/alert";
44
import { cn } from "@/lib/utils";
55
import { AlertCircle, CheckCircle } from "lucide-react";
66

@@ -51,7 +51,11 @@ export function LoginForm({
5151
<div className="flex flex-col gap-4">
5252
<a href="/api/auth/login">
5353
<Button variant="outline" className="w-full">
54-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" className="mr-2 h-4 w-4">
54+
<svg
55+
xmlns="http://www.w3.org/2000/svg"
56+
viewBox="0 0 24 24"
57+
className={`mr-2 h-4 w-4`}
58+
>
5559
<path
5660
d="M12.48 10.92v3.28h7.84c-.24 1.84-.853 3.187-1.787 4.133-1.147 1.147-2.933 2.4-6.053 2.4-4.827 0-8.6-3.893-8.6-8.72s3.773-8.72 8.6-8.72c2.6 0 4.507 1.027 5.907 2.347l2.307-2.307C18.747 1.44 16.133 0 12.48 0 5.867 0 .307 5.387.307 12s5.56 12 12.173 12c3.573 0 6.267-1.173 8.373-3.36 2.16-2.16 2.84-5.213 2.84-7.667 0-.76-.053-1.467-.173-2.053H12.48z"
5761
fill="currentColor"
@@ -70,7 +74,7 @@ export function LoginForm({
7074

7175
function getErrorMessage(error: string, description?: string): string {
7276
if (description) return description;
73-
77+
7478
switch (error) {
7579
case "invalid_request":
7680
return "登入請求無效,請重試。";

components/nav-user.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ export function NavUser({
4646
toast.error("登出失敗", {
4747
description: errorData.error_description || res.statusText,
4848
});
49-
49+
5050
// Even if server logout fails, redirect to clear client state
5151
window.location.href = "/login?error=logout_failed";
5252
} catch (error) {
5353
toast.error("登出失敗", {
5454
description: error instanceof Error ? error.message : "未知錯誤",
5555
});
56-
56+
5757
// Redirect to clear client state
5858
window.location.href = "/login?error=logout_failed";
5959
} finally {

lib/auth.rsc.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { redirect } from "next/navigation";
22
import { getAuthStatus } from "./auth";
33

44
export async function redirectIfAuthenticated(): Promise<void> {
5-
const isAuthenticated = await getAuthStatus();
6-
if (isAuthenticated.role === 'admin') {
7-
redirect("/");
8-
}
9-
}
5+
const isAuthenticated = await getAuthStatus();
6+
if (isAuthenticated.role === "admin") {
7+
redirect("/");
8+
}
9+
}

0 commit comments

Comments
 (0)