{"id":11344,"date":"2026-10-01T08:51:21","date_gmt":"2026-09-30T23:51:21","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=11344"},"modified":"2026-10-01T11:52:17","modified_gmt":"2026-10-01T02:52:17","slug":"nextjs-sns-server-43","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/10\/01\/nextjs-sns-server-43\/","title":{"rendered":"[nextjs]SNS Server-43(myapp53)\u00a0"},"content":{"rendered":"\n<p>\ud83d\udc49\ud83c\udffb myapp53\uc5d0\uc11c\ub294 \ubd80\uc2a4\ud2b8\uc640 \uc88b\uc544\uc694 \ubd80\ubd84 \ubcf4\uc548\uc744 \uac15\ud654\ud569\ub2c8\ub2e4.<br>myapp53 is strengthening security for the Boost and Like features.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \ub85c\uadf8\uc778 \ud558\uc9c0 \uc54a\uc73c\uba74 \ubd80\uc2a4\ud2b8\ub098 \uc88b\uc544\uc694\ub97c \ud074\ub9ad\ud558\uba74 \ub85c\uadf8\uc778\ud654\uba74\uc73c\ub85c \uc774\ub3d9\ud569\ub2c8\ub2e4.<br>If you are not logged in, clicking &#8220;Boost&#8221; or &#8220;Like&#8221; will redirect you to the login screen.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc0ac\uc6a9\ud558\uc9c0\uc54a\ub294 getToken\ud568\uc218\ub97c \uc0ad\uc81c\ud569\ub2c8\ub2e4.<br>Remove the unused getToken function.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \ub85c\uceec \uc11c\ubc84\uc5d0\uc11c  \uae00 \uc791\uc131\ud560 \ub54c \ucca8\ubd80 \ud30c\uc77c\uc774 \uc788\ub294 \uacbd\uc6b0 \ucca8\ubd80\ud30c\uc77c \ub9ac\uc2a4\ud2b8\uac00 \ucd08\uae30\ud654 \ub418\uc9c0 \uc54a\ub294 \ubb38\uc81c\ub97c \uc218\uc815\ud569\ub2c8\ub2e4.<br>Fixes an issue where the attachment list was not reset when creating a post with attachments on a local server.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc804\uccb4 \ucf54\ub4dc\ub294 \uae43\ud5c8\ube0c\uc5d0\uc11c \ud655\uc778 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>You can find the full code on GitHub.<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/gideonslife01\/flm-nextjs\">https:\/\/github.com\/gideonslife01\/flm-nextjs<\/a><\/p>\n\n\n\n<p>\ud83d\udcc1 \uc804\uccb4 \ud504\ub85c\uc81d\ud2b8 \uad6c\uc870 \/ Overall Project Structure<\/p>\n\n\n\n<pre class=\"wp-block-code\" style=\"font-size:14px\"><code>myapp project\/  \n\u251c\u2500\u2500 app\/  (Next.js App Router)\n\u2502   \u251c\u2500\u2500 .well-known\/webfinger\/route.ts  -&gt; webfinger\n\u2502   \u251c\u2500\u2500 api\/follow\/route.ts    -&gt; Follow API(temporary)\n\u2502   \u251c\u2500\u2500 api\/announce\/route.ts  -&gt; Boost(Announcement)\n\u2502   \u251c\u2500\u2500 api\/like\/route.ts.     -&gt; Like API\n\u2502   \u251c\u2500\u2500 api\/posts\/route.ts     -&gt; Writing API(deprecated)\n\u2502   \u251c\u2500\u2500 api\/timeline\/route.ts  -&gt; Timeline API\n\u2502   \u251c\u2500\u2500 api\/followinglist\/route.ts  -&gt; followinglist API\n\u2502   \u251c\u2500\u2500 api\/followerslist\/route.ts  -&gt; followerslist API\n\u2502   \u251c\u2500\u2500 <span style=\"background-color: initial; font-size: inherit; text-align: initial; color: initial;\">api\/v1\/instance<\/span>\/route.ts -&gt; auth\n\u2502   \u251c\u2500\u2500 api\/v1\/apps\/route.ts.    -&gt; auth\n\u2502   \u251c\u2500\u2500 api\/v1\/accounts\/verify_credentials\/route.ts -&gt; auth\n\u2502   \u251c\u2500\u2500 api\/v1\/statuses\/route.ts -&gt; Write Post\n\u2502   \u251c\u2500\u2500 <span style=\"background-color: initial; font-size: inherit; text-align: initial; color: initial;\">api\/v1\/timelines\/home\/route.ts<\/span> -&gt; timeline\n\u2502   \u251c\u2500\u2500 api\/v1\/media\/route.ts -&gt; Image upload\n\u2502   \u251c\u2500\u2500 api\/v1\/media\/&#91;id]\/route.ts  -&gt; Image Delete \n\u2502   \u251c\u2500\u2500 <span style=\"background-color: initial; font-size: inherit; text-align: initial; color: initial;\">oauth\/authorize\/route.ts<\/span> -&gt; auth\n\u2502   \u251c\u2500\u2500 <span style=\"background-color: initial; font-size: inherit; text-align: initial; color: initial;\">oauth\/token\/route.ts<\/span> -&gt; auth\n\u2502   \u251c\u2500\u2500 <span style=\"background-color: initial; font-size: inherit; text-align: initial; color: initial;\">api\/v1\/search\/home\/route.ts<\/span> -&gt; search\n\u2502   \u251c\u2500\u2500 <span style=\"background-color: initial; font-size: inherit; text-align: initial; color: initial;\">api\/v2\/search\/home\/route.ts<\/span> -&gt; search\n\u2502   \u251c\u2500\u2500 api\/v1\/accounts\/&#91;id]\/followers\/route.ts -&gt; followers\n\u2502   \u251c\u2500\u2500 api\/v1\/accounts\/&#91;id]\/following\/route.ts -&gt; following\n\u2502   \u251c\u2500\u2500 api\/v1\/statuses\/&#91;id]\/route.ts -&gt; -&gt; Post delete(pinafore)\n\u2502   \u251c\u2500\u2500 api\/auth\/signup\/route.ts        -&gt; Signup\n\u2502   \u251c\u2500\u2500 api\/auth\/login\/route.ts         -&gt; Login\n\u2502   \u251c\u2500\u2500<strong> <\/strong>api\/auth\/logout\/route.ts        -&gt; Logout\n\u2502   \u251c\u2500\u2500<strong> <\/strong>api\/auth\/refresh\/route.ts       -&gt; Refresh Token\n\u2502   \u251c\u2500\u2500<strong> <\/strong>api\/cleanup-orphan\/route.ts     -&gt; post,outbox clean up\n\u2502   \u251c\u2500\u2500<strong> <\/strong>api\/auth\/me\/route.tsx           -&gt; Login Check<strong>\n<\/strong>\u2502   \u251c\u2500\u2500 auth\/signup\/page.tsx            -&gt; Signup UI\n\u2502   \u251c\u2500\u2500 auth\/signup\/page.tsx            -&gt; Login UI\n\u2502   \u251c\u2500\u2500 users\/&#91;username]\/\n\u2502   \u2502   \u251c\u2500\u2500 statuses\/&#91;id]\/route.ts -&gt; Indivisual Post\n\u2502   \u2502   \u251c\u2500\u2500 route.ts               -&gt; Acotr Information\n\u2502   \u2502   \u251c\u2500\u2500 followers\/route.ts     -&gt; Followers List\n\u2502   \u2502   \u251c\u2500\u2500 following\/route.ts     -&gt; Following List\n\u2502   \u2502   \u251c\u2500\u2500 inbox\/route.ts         -&gt; Inbox\n\u2502   \u2502   \u2514\u2500\u2500 outbox\/route.ts        -&gt; outbox\n\u2502   \u251c\u2500\u2500 usersui\/&#91;username]\/\n\u2502   \u2502   \u251c\u2500\u2500 page.tsx               -&gt; Timeline UI(Server, 404)\n\u2502   \u2502   \u251c\u2500\u2500 ClientPage.tsx.        -&gt; Timeline UI(Client,Call Active Themes)\n\u2502   \u2502   \u2514\u2500\u2500 _components\/themes\/\n\u2502   \u2502       \u251c\u2500\u2500 themeex\/ThemeexTheme.tsx   -&gt; Example Theme\n\u2502   \u2502       \u251c\u2500\u2500 pinafore\/PinaforeTheme.tsx -&gt; Theme 1\n\u2502   \u2502       \u251c\u2500\u2500 pinafore\/FollowersList.tsx -&gt; Theme 1, FollowersList\n\u2502   \u2502       \u251c\u2500\u2500 pinafore\/FollowingList.tsx -&gt; Theme 1, FollowingList\n\u2502   \u2502       \u251c\u2500\u2500 pinafore\/NotificationsList.tsx -&gt; Theme 1, NotificationsList\n\u2502   \u2502       \u251c\u2500\u2500 mastodon\/MastodonTheme.tsx -&gt; Theme 2\n\u2502   \u2502       \u2514\u2500\u2500 minimal\/MinimaltTheme.tsx  -&gt; Theme 3\n\u2502   \u251c\u2500\u2500 layout.tsx, page.tsx, globals.css\n\u2502   \u2514\u2500\u2500 favicon.ico\n\u251c\u2500\u2500 lib\/\n\u2502   \u251c\u2500\u2500 theme.tsx              -&gt; Theme Provider\n\u2502   \u251c\u2500\u2500 watchThemes.ts         -&gt; Check real-time theme changes\n\u2502   \u251c\u2500\u2500 auth.ts                -&gt; Authentication, User Management\n\u2502   \u251c\u2500\u2500 ap.ts                  -&gt; Follow,Undo,Create,Likes,Announce\n\u2502   \u251c\u2500\u2500 visibility.ts          -&gt; Visibility(Public,Unlisted,Private,Direct)\n\u2502   \u2514\u2500\u2500 db.ts                  -&gt; DB connection\n\u251c\u2500\u2500 data\/\n\u2502   \u251c\u2500\u2500 keys\/userIDs\/          -&gt; private.pem, public.pem(New)\n\u2502   \u2514\u2500\u2500 keys\/                  -&gt; private.pem, public.pem(legacy)\n\u251c\u2500\u2500 data.sqlite                -&gt; Database(1\/3)\n\u251c\u2500\u2500 data.sqlite-wal            -&gt; Database(2\/3)\n\u251c\u2500\u2500 data.sqlite-shm            -&gt; Database(3\/3)\n\u251c\u2500\u2500 Caddyfile                  -&gt; https \n\u251c\u2500\u2500 instrumentation.ts         -&gt; Background Server\n\u2514\u2500\u2500 package.json<\/code><\/pre>\n\n\n\n<p>\ud83d\udcc1 \ud504\ub85c\uc81d\ud2b8 \uc2dc\uc791 \/ Project Start<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-freelifemakers-org wp-block-embed-freelifemakers-org\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"IgWocGeMPC\"><a href=\"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/09\/03\/nextjs-project-summary\/\">[nextjs]\ud504\ub85c\uc81d\ud2b8\uc694\uc57d\/project summary(myapp30+)<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;[nextjs]\ud504\ub85c\uc81d\ud2b8\uc694\uc57d\/project summary(myapp30+)&#8221; &#8212; freelifemakers.org\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/09\/03\/nextjs-project-summary\/embed\/#?secret=Kq8qVs44RQ#?secret=IgWocGeMPC\" data-secret=\"IgWocGeMPC\" width=\"560\" height=\"315\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83d\udcc1 \ucf54\ub4dc\uc218\uc815 \/ Code Modification<\/p>\n\n\n\n<p>\u2714\ufe0f \ubc84\uadf8 \uc218\uc815 \/ Bug fixes<\/p>\n\n\n\n<p>&#8212; \uae00 \uc791\uc131 \ud6c4 \uc774\ubbf8\uc9c0 \ucca8\ubd80 \ub9ac\uc2a4\ud2b8\uc640 \ud504\ub9ac\ubdf0\ub97c \ucd08\uae30\ud654 \ud569\ub2c8\ub2e4.<br>After posting, the list of attached images and the preview are reset.<\/p>\n\n\n\n<p>A.app\/usersui\/[username]\/_components\/themes\/pinafore\/PinaforeTheme.tsx<\/p>\n\n\n\n<pre class=\"wp-block-code\" style=\"font-size:14px\"><code>const handlePost = async () =&gt; {\n  if (!composeText.trim() || posting) return;\n  setPosting(true);\n  try {\n    \/\/ \ud1a0\ud070 \uc788\uc73c\uba74 \ud5e4\ub354\uc5d0 \ub123\uace0 \uc5c6\uc73c\uba74 \ucfe0\ud0a4 \uc778\uc99d\uc73c\ub85c\n    \/\/ Include the token in the header if present; otherwise, use cookie authentication.\n    const token = localStorage.getItem('access_token') || localStorage.getItem('token') || '';\n    const res = await fetch('\/api\/v1\/statuses', {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application\/json',\n         ...(token? { Authorization: `Bearer ${token}` } : {})\n      },\n      credentials: 'include',\n      body: JSON.stringify({ \n        status: composeText, \n        visibility: composeVis, \n        media_ids: mediaIds \/\/ \u2705 myapp51 - add media_ids\n      })\n    });\n    if (res.ok) {\n      const newPost = await res.json();\n      setComposeText('');\n      <strong>setMediaIds(&#91;]);<\/strong> \/\/ \u2705 myapp53 - \ucca8\ubd80 \ub9ac\uc2a4\ud2b8 \ucd08\uae30\ud654 \/ Reset attachment list\n      <strong>setPreviews(&#91;]);<\/strong> \/\/ \u2705 myapp53 - \ud504\ub9ac\ubdf0 \ucd08\uae30\ud654 \/ Reset Preview\n      \/\/ \ud0c0\uc784\ub77c\uc778 \ub9e8 \uc704\uc5d0 \uc989\uc2dc \ucd94\uac00 \/ Add immediately to the top of the timeline\n      setTimeline((prev: any&#91;]) =&gt; &#91;{\n        id: newPost.id, content: newPost.content, actor: `https:\/\/${DOMAIN}\/users\/${username}`,\n        username: username, \n        created_at: new Date().toISOString(), \n        source: 'local', \n        isMine: true, \n        visibility: composeVis,\n        media_attachments: newPost.media_attachments || &#91;] \/\/ \u2705 myap51 - preview\n      },...prev]);\n      setCounts(c =&gt; ({...c, posts: c.posts + 1}));\n    } else alert('\uac8c\uc2dc \uc2e4\ud328');\n    } catch (e) { console.error(e); alert('\uac8c\uc2dc \uc2e4\ud328'); }\n  setPosting(false);\n  \n};<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f \ubd80\uc2a4\ud2b8 \ubcf4\uc548\uac15\ud654 \/ Boost Security Enhancement<\/p>\n\n\n\n<p>&#8212; \ub85c\uadf8\uc778\ud558\uc9c0 \uc54a\uc73c\uba74 \ubd80\uc2a4\ud2b8 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\ub3c4\ub85d \ud569\ub2c8\ub2e4.<br>Disable the use of the boost function if the user is not logged in.<\/p>\n\n\n\n<p>A.app\/api\/announce\/route.ts &#8211; \ubc31\uc5d4\ub4dc \/ Backend<\/p>\n\n\n\n<pre class=\"wp-block-code\" style=\"font-size:14px\"><code>... ...\nfunction getUser(req: Request) {\n  const auth = req.headers.get('Authorization')?.replace('Bearer ','').trim();\n  if (auth) {\n    const o = db.prepare('SELECT username FROM oauth_tokens WHERE access_token=?').get(auth) as any;\n    if (o?.username) return o.username;\n  }\n  const cookie = req.headers.get('cookie') || '';\n  const m = cookie.match(\/refresh_token=(&#91;^;]+)\/);\n  if (m) {\n    const s = db.prepare('SELECT username FROM sessions WHERE refresh_token=?').get(m&#91;1]) as any;\n    if (s?.username) return s.username;\n  }\n  return null;\n}\n\nexport async function POST(req: NextRequest) {\n  try {\n    \/\/const { username, target } = await req.json();\n    const authUser = getUser(req);\n    if (!authUser) {\n      return NextResponse.json({ error: '\ub85c\uadf8\uc778 \ud544\uc694 \/ authentication required' }, { status: 401 });\n    }\n    const { target } = await req.json(); \n    const username = authUser; \n... ...\n}\n\nexport async function DELETE(req: NextRequest) {\n  try {\n    \/\/ \u2705 myapp53 - \ubd80\uc2a4\ud2b8 \uc0ad\uc81c \ubcf4\uc548\uac15\ud654 \/ Boost Removal &amp; Security Enhancement\n    \/\/const { username, target } = await req.json();\n    const authUser = getUser(req);\n    if (!authUser) {\n      return NextResponse.json({ error: '\ub85c\uadf8\uc778 \ud544\uc694\/ authentication required' }, { status: 401 });\n    }\n    const { target } = await req.json();\n    const username = authUser;\n... ...\n}<\/code><\/pre>\n\n\n\n<p>B.app\/usersui\/[username]\/_components\/themes\/pinafore\/PinaforeTheme.tsx &#8211; \ud504\ub860\ud2b8\uc5d4\ub4dc \/ Frontend<\/p>\n\n\n\n<p>a.\ubd80\uc2a4\ud2b8 \ubcf4\uc548\uac15\ud654 \/ Boost Security Enhancement<\/p>\n\n\n\n<pre class=\"wp-block-code\" style=\"font-size:14px\"><code>  ... ...\n  \/\/ \u2705 myapp53-boost-secure: \ubd80\uc2a4\ud2b8 \ubcf4\uc548\uac15\ud654 Boost Security Enhancement\n  const handleBoostClick = async (p: any) =&gt; {\n    if (!currentUser) return window.location.href = `\/auth\/login?next=\/@${username}`;\n    onBoost(p)\n  };\n\n  \/\/ \u2705 myapp53-boost-secure: \uc88b\uc544\uc694 \ubcf4\uc548\uac15\ud654 \/ Like Security Enhancement\n  const handleLikeClick = (p: any) =&gt; {\n    if (!currentUser) return window.location.href = `\/auth\/login?next=\/@${username}`;\n    onLike(p);\n  };\n... ...<\/code><\/pre>\n\n\n\n<p>b.\ubc84\uadf8\uc218\uc815(\uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 getToken\ud568\uc218 \ubd80\ubd84) \/ Bug fix (unused getToken function)<\/p>\n\n\n\n<pre class=\"wp-block-code\" style=\"font-size:14px\"><code>... ...\n\/\/ \u2705 deprecated(myapp53)-myapp51 - \ud1a0\ud070\uac00\uc838\uc624\uac00 , url \uacbd\ub85c\ubcf4\uc815 \/ Retrieve token, adjust URL path\n\/\/ \u2705 myapp53 - \ud1a0\ud070 \uc81c\uac70, \ucfe0\ud0a4 \uc778\uc99d\ub9cc \uc0ac\uc6a9 \/ cookie auth only\n\/\/const getToken = () =&gt; localStorage.getItem('access_token') || localStorage.getItem('token') || '';\n... ...\n \/\/ \u2705 myapp53 - cookie auth only\n \/\/const token = localStorage.getItem('access_token') || localStorage.getItem('token') || '';\nconst handleDelete = async (postId: string) =&gt; {\n... ...\n    const res = await fetch(`\/api\/v1\/statuses\/${postId}`, { \n      method: 'DELETE',\n      \/\/ headers: {\n      \/\/   ...(token? { Authorization: `Bearer ${token}` } : {})\n      \/\/ },\n      credentials: 'include' \/\/ refresh_token \ucfe0\ud0a4 \ud3ec\ud568 \/ Include refresh_token cookie\n    });\n... ...\n}\n... ...\nconst handlePost = async () =&gt; {\n... ...\n    \/\/ \u2705 myapp53 - cookie auth only\n    const res = await fetch('\/api\/v1\/statuses', {\n      method: 'POST',\n      \/\/ headers: {\n      \/\/   'Content-Type': 'application\/json',\n      \/\/    ...(token? { Authorization: `Bearer ${token}` } : {})\n      \/\/ },\n      credentials: 'include',\n      body: JSON.stringify({ \n        status: composeText, \n        visibility: composeVis, \n        media_ids: mediaIds \/\/ \u2705 myapp51 - add media_ids\n      })\n    });\n... ...\n    if (res.ok) {\n      const newPost = await res.json();\n      setComposeText('');\n      setMediaIds(&#91;]); \/\/ \u2705 myapp53 - \ucca8\ubd80 \ub9ac\uc2a4\ud2b8 \ucd08\uae30\ud654 \/ Reset attachment list\n      setPreviews(&#91;]); \/\/ \u2705 myapp53 - \ud504\ub9ac\ubdf0 \ucd08\uae30\ud654 \/ Reset Preview\n... ...\n    }\n... ...\n}\n\nasync function onFiles(e: React.ChangeEvent&lt;HTMLInputElement&gt;) {\n    \/\/ \u2705 myapp53 - Cookie auth only\n    \/\/const token = getToken();\n... ...\n        const res = await fetch('\/api\/v1\/media', {\n          method: 'POST',\n          body: fd,\n          \/\/headers: {...(token? { Authorization: `Bearer ${token}` } : {}) },\/\/ \u2705 myapp53 - Cookie auth only\n          credentials: 'include'\n        });\n... ...\n}\n\n<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f \uc88b\uc544\uc694 \ubcf4\uc548\uac15\ud654 \/ Like Security Enhancement<\/p>\n\n\n\n<p>&#8212; \ub85c\uadf8\uc778\ud558\uc9c0 \uc54a\uc73c\uba74 \uc88b\uc544\uc694 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\ub3c4\ub85d \ud569\ub2c8\ub2e4.<br>Disable the &#8216;like&#8217; function for users who are not logged in.<\/p>\n\n\n\n<p>A.app\/api\/announce\/route.ts &#8211; \ubc31\uc5d4\ub4dc \/ Backend<\/p>\n\n\n\n<pre class=\"wp-block-code\" style=\"font-size:14px\"><code>... ...\nfunction getUser(req: Request) {\n  const auth = req.headers.get('Authorization')?.replace('Bearer ','').trim();\n  if (auth) {\n    const o = db.prepare('SELECT username FROM oauth_tokens WHERE access_token=?').get(auth) as any;\n    if (o?.username) return o.username;\n  }\n  const cookie = req.headers.get('cookie') || '';\n  const m = cookie.match(\/refresh_token=(&#91;^;]+)\/);\n  if (m) {\n    const s = db.prepare('SELECT username FROM sessions WHERE refresh_token=?').get(m&#91;1]) as any;\n    if (s?.username) return s.username;\n  }\n  return null;\n}\n\nexport async function POST(req: NextRequest) {\n  \/\/const { username, target } = await req.json();\n  \/\/ \u2705 myapp53 - \uc88b\uc544\uc694 \ubcf4\uc548\uac15\ud654 \/ like Security Enhancement\n  \/\/const { username, target } = await req.json();\n  const authUser = getUser(req);\n  if (!authUser) {\n    return NextResponse.json({ error: '\ub85c\uadf8\uc778 \ud544\uc694 \/ authentication required' }, { status: 401 });\n  }\n  const { target } = await req.json();\n  const username = authUser;\n... ...\n}\n\nexport async function DELETE(req: NextRequest) {\n\n  \/\/ \u2705 myapp53 - \uc88b\uc544\uc694 \ubcf4\uc548\uac15\ud654 \/ like Security Enhancement\n  \/\/const { username, target } = await req.json();\n  const authUser = getUser(req);\n  if (!authUser) {\n    return NextResponse.json({ error: '\ub85c\uadf8\uc778 \ud544\uc694 \/ authentication required' }, { status: 401 });\n  }\n  const { target } = await req.json();\n  const username = authUser;\n... ...\n}<\/code><\/pre>\n\n\n\n<p>B.app\/usersui\/[username]\/_components\/themes\/pinafore\/PinaforeTheme.tsx &#8211; \ud504\ub860\ud2b8\uc5d4\ub4dc \/ Frontend<\/p>\n\n\n\n<p>&#8212;  \uc704\uc758 \ubd80\uc2a4\ud2b8 \ubcf4\uc548\uac15\ud654 \ubd80\ubd84\uc758 \ucf54\ub4dc\ub97c \ucc38\uc870\ud558\uc138\uc694<br>Please refer to the code in the Boost security enhancement section above.<\/p>\n\n\n\n<p>\ud83d\udcc1 \ud14c\uc2a4\ud2b8 \/ Test<\/p>\n\n\n\n<p>\u2714\ufe0f \ucca8\ubd80\ud30c\uc77c \ub9ac\uc2a4\ud2b8 \ucd08\uae30\ud654 \ud14c\uc2a4\ud2b8<br>Attachment list reset test<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"677\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-image-test-jpg-1024x677.jpg\" alt=\"\" class=\"wp-image-11391\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-image-test-jpg-1024x677.jpg 1024w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-image-test-jpg-300x198.jpg 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-image-test-jpg-768x508.jpg 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-image-test-jpg-1536x1016.jpg 1536w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-image-test-jpg-2048x1354.jpg 2048w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-image-test-jpg-1870x1236.jpg 1870w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-image-test-jpg-400x264.jpg 400w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-image-test-jpg-800x529.jpg 800w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Attachment list reset<\/figcaption><\/figure>\n\n\n\n<p>\u2714\ufe0f \ub85c\uadf8\uc544\uc6c3\uc2dc \uc88b\uc544\uc694,\ubd80\uc2a4\ud2b8 \ud074\ub9ad\ud558\uba74 \ub85c\uadf8\uc778 \ud398\uc774\uc9c0\ub85c \uc774\ub3d9<br>If you click &#8220;Like&#8221; or &#8220;Boost&#8221; while logged out, you will be redirected to the login page.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"970\" height=\"673\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-move-page-jpg.jpg\" alt=\"\" class=\"wp-image-11389\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-move-page-jpg.jpg 970w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-move-page-jpg-300x208.jpg 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-move-page-jpg-768x533.jpg 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-move-page-jpg-400x278.jpg 400w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-move-page-jpg-800x555.jpg 800w\" sizes=\"auto, (max-width: 970px) 100vw, 970px\" \/><\/figure>\n\n\n\n<p>\u2714\ufe0f \ub85c\uadf8\uc778\uc2dc \uc88b\uc544\uc694,\ubd80\uc2a4\ud2b8 \uc791\ub3d9\ud655\uc778<br>Verify that &#8216;Like&#8217; and &#8216;Boost&#8217; functions work upon login.<\/p>\n\n\n\n<p>&#8212; Local Server<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"433\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-aloy-jpg.jpg\" alt=\"\" class=\"wp-image-11385\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-aloy-jpg.jpg 800w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-aloy-jpg-300x162.jpg 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-aloy-jpg-768x416.jpg 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-aloy-jpg-400x217.jpg 400w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Local Server<\/figcaption><\/figure>\n\n\n\n<p>&#8212; GTS Server<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"360\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-gts-jpg.jpg\" alt=\"\" class=\"wp-image-11382\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-gts-jpg.jpg 800w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-gts-jpg-300x135.jpg 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-gts-jpg-768x346.jpg 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/10\/myapp53-gts-jpg-400x180.jpg 400w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">GTS Server<\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\uc694\ud55c\ubcf5\uc74c 8\uc7a5 32\uc808 \/ John 8:32<\/p>\n\n\n\n<p>&#8220;\uadf8\ub9ac\uace0 \ub108\ud76c\ub294 \uc9c4\ub9ac\ub97c \uc54c\uac8c \ub420 \uac83\uc774\uba70, \uc9c4\ub9ac\uac00 \ub108\ud76c\ub97c \uc790\uc720\ub86d\uac8c \ud560 \uac83\uc774\ub2e4.&#8221;<\/p>\n\n\n\n<p>&#8220;Then you will know the truth ,and the truth will set you free&#8221;<\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49\ud83c\udffb myapp53\uc5d0\uc11c\ub294 \ubd80\uc2a4\ud2b8\uc640 \uc88b\uc544\uc694 \ubd80\ubd84 \ubcf4\uc548\uc744 \uac15\ud654\ud569\ub2c8\ub2e4.myapp53 is strengthening security for the Boost and Like features. \ud83d\udc49\ud83c\udffb \ub85c\uadf8\uc778 \ud558\uc9c0 \uc54a\uc73c\uba74 \ubd80\uc2a4\ud2b8\ub098 \uc88b\uc544\uc694\ub97c \ud074\ub9ad\ud558\uba74 \ub85c\uadf8\uc778\ud654\uba74\uc73c\ub85c \uc774\ub3d9\ud569\ub2c8\ub2e4.If you are not logged in, clicking &#8220;Boost&#8221; or &#8220;Like&#8221; will redirect you to the login screen. \ud83d\udc49\ud83c\udffb \uc0ac\uc6a9\ud558\uc9c0\uc54a\ub294 getToken\ud568\uc218\ub97c \uc0ad\uc81c\ud569\ub2c8\ub2e4.Remove the unused getToken function. \ud83d\udc49\ud83c\udffb \ub85c\uceec \uc11c\ubc84\uc5d0\uc11c \uae00 \uc791\uc131\ud560 \ub54c [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":11389,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[28,27,1,7,29],"tags":[],"class_list":["post-11344","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news","category-nextjs","category-uncategorized","category-website","category-webui","has-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/11344","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=11344"}],"version-history":[{"count":42,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/11344\/revisions"}],"predecessor-version":[{"id":11393,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/11344\/revisions\/11393"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media\/11389"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=11344"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=11344"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=11344"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}