Skip to content

Commit

Permalink
Merge pull request #485 from s-hirano-ist/fix--security-issue-due-to-…
Browse files Browse the repository at this point in the history
…use-server

fix: 🐛 security issue due to  use server
  • Loading branch information
s-hirano-ist authored Oct 14, 2024
2 parents f6c8134 + a0aa3ca commit 1ec7fe4
Show file tree
Hide file tree
Showing 26 changed files with 73 additions and 71 deletions.
4 changes: 4 additions & 0 deletions src/apis/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# NOTES

- `"use server";`を入れると外部に公開されてしまうため、入力不可。
- クライアントサイドからのアクセスを禁止したいため、`"import "server-only";`は入力必須。
3 changes: 1 addition & 2 deletions src/apis/line-notify/fetch-message.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use server";
import "server-only";
import { env } from "@/env.mjs";
import { LineNotifyError } from "@/error";
import { LineNotifyError } from "@/error-classes";

export async function sendLineNotifyMessage(message: string) {
const LINE_NOTIFY_URL = env.LINE_NOTIFY_URL;
Expand Down
1 change: 0 additions & 1 deletion src/apis/markdown/fetch-contents.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// "use server"; // MEMO: commented because functions are not async functions.
import "server-only";
import fs from "node:fs";
import { join } from "node:path";
Expand Down
1 change: 0 additions & 1 deletion src/apis/prisma/fetch-category.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
"use server";
import "server-only";
import { getUserId } from "@/features/auth/utils/get-session";
import type { validateCategory } from "@/features/dump/utils/validate-category";
Expand Down
3 changes: 1 addition & 2 deletions src/apis/prisma/fetch-contents.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use server";
import "server-only";
import { NotAllowedError } from "@/error";
import { NotAllowedError } from "@/error-classes";
import { getSelfRole, getUserId } from "@/features/auth/utils/get-session";
import type { validateContents } from "@/features/dump/utils/validate-contents";
import type { Status } from "@/features/update-status/types";
Expand Down
1 change: 0 additions & 1 deletion src/apis/prisma/fetch-login-history.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
"use server";
import "server-only";
import prisma from "@/prisma";
import { getUserIdForLoginHistory } from "./fetch-user";
Expand Down
3 changes: 1 addition & 2 deletions src/apis/prisma/fetch-news.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use server";
import "server-only";
import { NotAllowedError } from "@/error";
import { NotAllowedError } from "@/error-classes";
import { getSelfRole, getUserId } from "@/features/auth/utils/get-session";
import type { validateNews } from "@/features/dump/utils/validate-news";
import type { Status } from "@/features/update-status/types";
Expand Down
1 change: 0 additions & 1 deletion src/apis/prisma/fetch-profile.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
"use server";
import "server-only";
import { getUserId } from "@/features/auth/utils/get-session";
import type { ProfileSchema } from "@/features/profile/schemas/profile-schema";
Expand Down
3 changes: 1 addition & 2 deletions src/apis/prisma/fetch-user.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use server";
import "server-only";
import { NotAllowedError } from "@/error";
import { NotAllowedError } from "@/error-classes";
import { getUserId } from "@/features/auth/utils/get-session";
import prisma from "@/prisma";
import type { Scope } from "@prisma/client";
Expand Down
36 changes: 36 additions & 0 deletions src/error-classes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ERROR_MESSAGES, FORM_ERROR_MESSAGES } from "./constants";

export class LineNotifyError extends Error {
constructor() {
super(ERROR_MESSAGES.LINE_SEND);
this.name = "LineNotifyError";
}
}

export class NotAllowedError extends Error {
constructor() {
super(ERROR_MESSAGES.NOT_ALLOWED);
this.name = "NotAllowedError";
}
}

export class UnauthorizedError extends Error {
constructor() {
super(ERROR_MESSAGES.UNAUTHORIZED);
this.name = "UnauthorizedError";
}
}

export class UnexpectedError extends Error {
constructor() {
super(ERROR_MESSAGES.UNEXPECTED);
this.name = "UnexpectedError";
}
}

export class InvalidFormatError extends Error {
constructor() {
super(FORM_ERROR_MESSAGES.INVALID_FORMAT);
this.name = "InvalidFormatError";
}
}
46 changes: 10 additions & 36 deletions src/error.ts → src/error-wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
"use server";
import "server-only";
import { Prisma } from "@prisma/client";
import { AuthError } from "next-auth";
import { sendLineNotifyMessage } from "./apis/line-notify/fetch-message";
import { ERROR_MESSAGES, FORM_ERROR_MESSAGES } from "./constants";
import { ERROR_MESSAGES } from "./constants";
import {
InvalidFormatError,
LineNotifyError,
NotAllowedError,
UnauthorizedError,
UnexpectedError,
} from "./error-classes";
import type { ServerAction } from "./types";

export async function wrapServerSideErrorForClient<T>(
Expand Down Expand Up @@ -64,38 +73,3 @@ export async function wrapServerSideErrorForClient<T>(
}
return { success: false, message: ERROR_MESSAGES.UNEXPECTED };
}

export class LineNotifyError extends Error {
constructor() {
super(ERROR_MESSAGES.LINE_SEND);
this.name = "LineNotifyError";
}
}

export class NotAllowedError extends Error {
constructor() {
super(ERROR_MESSAGES.NOT_ALLOWED);
this.name = "NotAllowedError";
}
}

export class UnauthorizedError extends Error {
constructor() {
super(ERROR_MESSAGES.UNAUTHORIZED);
this.name = "UnauthorizedError";
}
}

export class UnexpectedError extends Error {
constructor() {
super(ERROR_MESSAGES.UNEXPECTED);
this.name = "UnexpectedError";
}
}

export class InvalidFormatError extends Error {
constructor() {
super(FORM_ERROR_MESSAGES.INVALID_FORMAT);
this.name = "InvalidFormatError";
}
}
2 changes: 1 addition & 1 deletion src/features/auth/actions/sign-in.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import "server-only";
import { sendLineNotifyMessage } from "@/apis/line-notify/fetch-message";
import { createSelfLoginHistory } from "@/apis/prisma/fetch-login-history";
import { SUCCESS_MESSAGES } from "@/constants";
import { wrapServerSideErrorForClient } from "@/error";
import { wrapServerSideErrorForClient } from "@/error-wrapper";
import type { SignInSchema } from "@/features/auth/schemas/sign-in-schema";
import { signIn as NextAuthSignIn } from "@/features/auth/utils/auth";
import { getLoginUserInfo } from "@/features/auth/utils/header-info";
Expand Down
2 changes: 1 addition & 1 deletion src/features/auth/actions/sign-out.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import "server-only";
import { sendLineNotifyMessage } from "@/apis/line-notify/fetch-message";
import { SUCCESS_MESSAGES } from "@/constants";
import { wrapServerSideErrorForClient } from "@/error";
import { wrapServerSideErrorForClient } from "@/error-wrapper";
import { signOut as NextAuthSignOut } from "@/features/auth/utils/auth";
import type { ServerAction } from "@/types";

Expand Down
2 changes: 1 addition & 1 deletion src/features/auth/utils/get-session.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use server";
import "server-only";
import { UnauthorizedError } from "@/error";
import { UnauthorizedError } from "@/error-classes";
// import { redirect } from "next/navigation";
import { auth } from "./auth";

Expand Down
2 changes: 1 addition & 1 deletion src/features/auth/utils/role.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use server";
import "server-only";
import { getUserScope } from "@/apis/prisma/fetch-user";
import { UnexpectedError } from "@/error";
import { UnexpectedError } from "@/error-classes";
import { checkSelfAuth } from "./get-session";

// FOR /contents/* and /all
Expand Down
3 changes: 2 additions & 1 deletion src/features/dump/actions/add-contents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import "server-only";
import { sendLineNotifyMessage } from "@/apis/line-notify/fetch-message";
import { createSelfContents } from "@/apis/prisma/fetch-contents";
import { SUCCESS_MESSAGES } from "@/constants";
import { NotAllowedError, wrapServerSideErrorForClient } from "@/error";
import { NotAllowedError } from "@/error-classes";
import { wrapServerSideErrorForClient } from "@/error-wrapper";
import { checkPostPermission } from "@/features/auth/utils/role";
import type { ContentsContext } from "@/features/dump/stores/contents-context";
import { validateContents } from "@/features/dump/utils/validate-contents";
Expand Down
3 changes: 2 additions & 1 deletion src/features/dump/actions/add-news.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { sendLineNotifyMessage } from "@/apis/line-notify/fetch-message";
import { createSelfCategory } from "@/apis/prisma/fetch-category";
import { createSelfNews } from "@/apis/prisma/fetch-news";
import { SUCCESS_MESSAGES } from "@/constants";
import { NotAllowedError, wrapServerSideErrorForClient } from "@/error";
import { NotAllowedError } from "@/error-classes";
import { wrapServerSideErrorForClient } from "@/error-wrapper";
import { checkPostPermission } from "@/features/auth/utils/role";
import type { NewsContext } from "@/features/dump/stores/news-context";
import { validateCategory } from "@/features/dump/utils/validate-category";
Expand Down
2 changes: 1 addition & 1 deletion src/features/dump/utils/validate-category.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "server-only";
import { InvalidFormatError } from "@/error";
import { InvalidFormatError } from "@/error-classes";
import { categorySchema } from "@/features/dump/schemas/category-schema";

export function validateCategory(formData: FormData) {
Expand Down
2 changes: 1 addition & 1 deletion src/features/dump/utils/validate-contents.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "server-only";
import { InvalidFormatError } from "@/error";
import { InvalidFormatError } from "@/error-classes";
import { contentsSchema } from "@/features/dump/schemas/contents-schema";

export function validateContents(formData: FormData) {
Expand Down
2 changes: 1 addition & 1 deletion src/features/dump/utils/validate-news.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "server-only";
import { InvalidFormatError } from "@/error";
import { InvalidFormatError } from "@/error-classes";
import { newsSchema } from "@/features/dump/schemas/news-schema";

export function validateNews(formData: FormData) {
Expand Down
2 changes: 1 addition & 1 deletion src/features/profile/actions/change-profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import "server-only";
import { sendLineNotifyMessage } from "@/apis/line-notify/fetch-message";
import { upsertSelfProfile } from "@/apis/prisma/fetch-profile";
import { SUCCESS_MESSAGES } from "@/constants";
import { wrapServerSideErrorForClient } from "@/error";
import { wrapServerSideErrorForClient } from "@/error-wrapper";
import type { ProfileSchema } from "@/features/profile/schemas/profile-schema";
import type { ServerAction } from "@/types";
import { formatUpsertProfileMessage } from "@/utils/format-for-line";
Expand Down
2 changes: 1 addition & 1 deletion src/features/profile/actions/change-scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import "server-only";
import { sendLineNotifyMessage } from "@/apis/line-notify/fetch-message";
import { updateSelfScope } from "@/apis/prisma/fetch-user";
import { SUCCESS_MESSAGES } from "@/constants";
import { wrapServerSideErrorForClient } from "@/error";
import { wrapServerSideErrorForClient } from "@/error-wrapper";
import type { ServerAction } from "@/types";
import { formatUpdateScopeMessage } from "@/utils/format-for-line";

Expand Down
7 changes: 2 additions & 5 deletions src/features/update-status/actions/change-contents-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ import {
updateSelfContentsStatus,
} from "@/apis/prisma/fetch-contents";
import { SUCCESS_MESSAGES } from "@/constants";
import {
NotAllowedError,
UnexpectedError,
wrapServerSideErrorForClient,
} from "@/error";
import { NotAllowedError, UnexpectedError } from "@/error-classes";
import { wrapServerSideErrorForClient } from "@/error-wrapper";
import { checkUpdateStatusPermission } from "@/features/auth/utils/role";
import type { UpdateOrRevert } from "@/features/update-status/types";
import type { ServerAction } from "@/types";
Expand Down
7 changes: 2 additions & 5 deletions src/features/update-status/actions/change-news-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ import {
updateSelfNewsStatus,
} from "@/apis/prisma/fetch-news";
import { SUCCESS_MESSAGES } from "@/constants";
import {
NotAllowedError,
UnexpectedError,
wrapServerSideErrorForClient,
} from "@/error";
import { NotAllowedError, UnexpectedError } from "@/error-classes";
import { wrapServerSideErrorForClient } from "@/error-wrapper";
import { checkUpdateStatusPermission } from "@/features/auth/utils/role";
import type { UpdateOrRevert } from "@/features/update-status/types";
import type { ServerAction } from "@/types";
Expand Down
2 changes: 1 addition & 1 deletion src/features/update-status/components/dump-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
import { UnexpectedError } from "@/error";
import { UnexpectedError } from "@/error-classes";
import type { ContentsContext } from "@/features/dump/stores/contents-context";
import type { NewsContext } from "@/features/dump/stores/news-context";
import type { ContentName } from "@/features/dump/types";
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
"paths": { "@/*": ["./src/*"] }
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules", "script"]
"exclude": ["node_modules", "script/**/*", "README.md"]
}

0 comments on commit 1ec7fe4

Please sign in to comment.