From d9b33357f41919b49108dab6c77eff2dac347c87 Mon Sep 17 00:00:00 2001 From: niko <57009359+hauntii@users.noreply.github.com> Date: Sat, 19 Apr 2025 19:47:45 -0400 Subject: [PATCH 1/4] Add login & update configurations --- .gitattributes | 2 +- nuxt.config.ts | 4 + src/pages/account/index.vue | 5 + src/pages/account/login/index.vue | 239 +++++++++++++++++++++++ src/server/api/account/login/index.ts | 25 +++ src/server/api/account/login/refresh.ts | 1 + src/server/api/account/register/index.ts | 1 + src/server/tsconfig.json | 2 +- 8 files changed, 277 insertions(+), 2 deletions(-) create mode 100644 src/pages/account/index.vue create mode 100644 src/pages/account/login/index.vue create mode 100644 src/server/api/account/login/index.ts create mode 100644 src/server/api/account/login/refresh.ts create mode 100644 src/server/api/account/register/index.ts diff --git a/.gitattributes b/.gitattributes index 176a458..94f480d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -* text=auto +* text=auto eol=lf \ No newline at end of file diff --git a/nuxt.config.ts b/nuxt.config.ts index 2d5787d..574b3f9 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -23,6 +23,10 @@ export default defineNuxtConfig({ } }, + runtimeConfig: { + apiBase: 'https://api.pretendo.cc' + }, + css: ['~/assets/css/main.css'], fonts: { diff --git a/src/pages/account/index.vue b/src/pages/account/index.vue new file mode 100644 index 0000000..45a26af --- /dev/null +++ b/src/pages/account/index.vue @@ -0,0 +1,5 @@ + + + account stub page + + diff --git a/src/pages/account/login/index.vue b/src/pages/account/login/index.vue new file mode 100644 index 0000000..2fa873e --- /dev/null +++ b/src/pages/account/login/index.vue @@ -0,0 +1,239 @@ + + + + + + + {{ $t("account.loginForm.login") }} + {{ $t("account.loginForm.detailsPrompt") }} + + {{ $t("account.loginForm.username") }} + + + + {{ $t("account.loginForm.password") }} + + {{ $t("account.loginForm.forgotPassword") }} + + + + + + {{ $t("account.loginForm.login") }} + + {{ $t("account.loginForm.registerPrompt") }} + + + + + + {{ errorMessage }} + + + + + + + + diff --git a/src/server/api/account/login/index.ts b/src/server/api/account/login/index.ts new file mode 100644 index 0000000..d13e0c4 --- /dev/null +++ b/src/server/api/account/login/index.ts @@ -0,0 +1,25 @@ +export default defineEventHandler(async (event) => { + const body = await readBody(event); + const apiResponse = await fetch(`${useRuntimeConfig(event).apiBase}/v1/login`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ ...body, grant_type: 'password' }) + }); + const apiJSON = await apiResponse.json(); + + if (!apiResponse.ok) { + setResponseStatus(event, apiResponse.status, apiJSON.error); + event.node.res.end(); + + return; + } + + setCookie(event, 'refresh_token', apiJSON.refresh_token); + setCookie(event, 'access_token', apiJSON.access_token); + setCookie(event, 'token_type', apiJSON.token_type); + + setResponseStatus(event, 200); + event.node.res.end(); +}); diff --git a/src/server/api/account/login/refresh.ts b/src/server/api/account/login/refresh.ts new file mode 100644 index 0000000..25be858 --- /dev/null +++ b/src/server/api/account/login/refresh.ts @@ -0,0 +1 @@ +// TODO: endpoint for refreshing tokens diff --git a/src/server/api/account/register/index.ts b/src/server/api/account/register/index.ts new file mode 100644 index 0000000..7a1488f --- /dev/null +++ b/src/server/api/account/register/index.ts @@ -0,0 +1 @@ +// TODO: registration diff --git a/src/server/tsconfig.json b/src/server/tsconfig.json index b9ed69c..3c6e968 100644 --- a/src/server/tsconfig.json +++ b/src/server/tsconfig.json @@ -1,3 +1,3 @@ { - "extends": "../.nuxt/tsconfig.server.json" + "extends": "../../.nuxt/tsconfig.server.json" } From 25a298c87dd0e1935b4585b6888764b875f3524e Mon Sep 17 00:00:00 2001 From: niko <57009359+hauntii@users.noreply.github.com> Date: Sat, 19 Apr 2025 20:20:01 -0400 Subject: [PATCH 2/4] Switch to ofetch methods and fix redirection --- src/pages/account/login/index.vue | 23 +++++++------- src/server/api/account/login/index.ts | 45 +++++++++++++++++---------- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/pages/account/login/index.vue b/src/pages/account/login/index.vue index 2fa873e..ccde674 100644 --- a/src/pages/account/login/index.vue +++ b/src/pages/account/login/index.vue @@ -1,4 +1,6 @@ diff --git a/src/server/api/account/login/index.ts b/src/server/api/account/login/index.ts index d13e0c4..440a01c 100644 --- a/src/server/api/account/login/index.ts +++ b/src/server/api/account/login/index.ts @@ -1,25 +1,36 @@ +import { FetchError } from 'ofetch'; + +type LoginCCResponse = { + refresh_token: string; + access_token: string; + token_type: string; + expires_in: number; +}; + export default defineEventHandler(async (event) => { const body = await readBody(event); - const apiResponse = await fetch(`${useRuntimeConfig(event).apiBase}/v1/login`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ ...body, grant_type: 'password' }) - }); - const apiJSON = await apiResponse.json(); - if (!apiResponse.ok) { - setResponseStatus(event, apiResponse.status, apiJSON.error); + try { + const apiResponse = await $fetch(`${useRuntimeConfig(event).apiBase}/v1/login`, { + method: 'POST', + body: { ...body, grant_type: 'password' } + }); + + setCookie(event, 'refresh_token', apiResponse.refresh_token); + setCookie(event, 'access_token', apiResponse.access_token); + setCookie(event, 'token_type', apiResponse.token_type); + + setResponseStatus(event, 200); + event.node.res.end(); + } catch (error: unknown) { + if (error instanceof FetchError) { + setResponseStatus(event, error.status, error.data.error); + } else { + setResponseStatus(event, 500); + } + event.node.res.end(); return; } - - setCookie(event, 'refresh_token', apiJSON.refresh_token); - setCookie(event, 'access_token', apiJSON.access_token); - setCookie(event, 'token_type', apiJSON.token_type); - - setResponseStatus(event, 200); - event.node.res.end(); }); From 51d5c3d2e18735c54dd5d360a7c36104b5da36dc Mon Sep 17 00:00:00 2001 From: niko <57009359+hauntii@users.noreply.github.com> Date: Mon, 21 Apr 2025 12:06:27 -0400 Subject: [PATCH 3/4] fix: small fixes --- src/pages/account/login/index.vue | 8 +------- src/server/api/account/login/index.ts | 3 ++- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/pages/account/login/index.vue b/src/pages/account/login/index.vue index ccde674..e16c927 100644 --- a/src/pages/account/login/index.vue +++ b/src/pages/account/login/index.vue @@ -5,7 +5,7 @@ const route = useRoute(); const redirect = route.query.redirect; const registerURI = `/account/register${redirect ? `?redirect=${redirect}` : ''}`; -const loginForm = reactive({ username: null, password: null }); +const loginForm = reactive({ username: '', password: '' }); const errorMessage = ref(); async function loginSubmission() { @@ -61,12 +61,6 @@ async function loginSubmission() { class="pwdreset" >{{ $t("account.loginForm.forgotPassword") }} - diff --git a/src/server/api/account/login/index.ts b/src/server/api/account/login/index.ts index 440a01c..61c2407 100644 --- a/src/server/api/account/login/index.ts +++ b/src/server/api/account/login/index.ts @@ -11,8 +11,9 @@ export default defineEventHandler(async (event) => { const body = await readBody(event); try { - const apiResponse = await $fetch(`${useRuntimeConfig(event).apiBase}/v1/login`, { + const apiResponse = await $fetch(`/v1/login`, { method: 'POST', + baseURL: useRuntimeConfig(event).apiBase, body: { ...body, grant_type: 'password' } }); From 38459965b4b31a95db81f71c5f38c56dc998762c Mon Sep 17 00:00:00 2001 From: niko <57009359+hauntii@users.noreply.github.com> Date: Mon, 21 Apr 2025 21:24:51 -0400 Subject: [PATCH 4/4] fix: redirect is computed --- src/pages/account/login/index.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/account/login/index.vue b/src/pages/account/login/index.vue index e16c927..f2a0e88 100644 --- a/src/pages/account/login/index.vue +++ b/src/pages/account/login/index.vue @@ -2,8 +2,8 @@ import { FetchError } from 'ofetch'; const route = useRoute(); -const redirect = route.query.redirect; -const registerURI = `/account/register${redirect ? `?redirect=${redirect}` : ''}`; +const redirect = computed(() => route.query.redirect); +const registerURI = computed(() => `/account/register${redirect.value ? `?redirect=${redirect.value}` : ''}`); const loginForm = reactive({ username: '', password: '' }); const errorMessage = ref(); @@ -21,8 +21,8 @@ async function loginSubmission() { return; }); - if (typeof redirect === 'string') { - await navigateTo(redirect); + if (typeof redirect.value === 'string') { + await navigateTo(redirect.value); } else { await navigateTo('/account'); }
account stub page
{{ $t("account.loginForm.detailsPrompt") }}
{{ errorMessage }}