@frigear-nu/account 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +15 -6
  2. package/dist/module.d.mts +31 -0
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +41 -36
  5. package/dist/runtime/app/components/Account/AccountHeader.d.vue.ts +3 -0
  6. package/dist/runtime/app/components/Account/AccountHeader.vue +59 -0
  7. package/dist/runtime/app/components/Account/AccountHeader.vue.d.ts +3 -0
  8. package/dist/runtime/app/components/Account/AccountMenu.vue +7 -2
  9. package/dist/runtime/app/components/Account/IdentificationCode.d.vue.ts +3 -0
  10. package/dist/runtime/app/components/Account/IdentificationCode.vue +82 -0
  11. package/dist/runtime/app/components/Account/IdentificationCode.vue.d.ts +3 -0
  12. package/dist/runtime/app/components/Account/IdentificationCodeDialog.d.vue.ts +20 -0
  13. package/dist/runtime/app/components/Account/IdentificationCodeDialog.vue +16 -0
  14. package/dist/runtime/app/components/Account/IdentificationCodeDialog.vue.d.ts +20 -0
  15. package/dist/runtime/app/composables/useAccount.js +3 -3
  16. package/dist/runtime/app/pages/api-tokens.d.vue.ts +3 -0
  17. package/dist/runtime/app/pages/api-tokens.vue +308 -0
  18. package/dist/runtime/app/pages/api-tokens.vue.d.ts +3 -0
  19. package/dist/runtime/app/pages/documents.d.vue.ts +3 -0
  20. package/dist/runtime/app/pages/documents.vue +38 -0
  21. package/dist/runtime/app/pages/documents.vue.d.ts +3 -0
  22. package/dist/runtime/app/pages/id-code.d.vue.ts +3 -0
  23. package/dist/runtime/app/pages/id-code.vue +13 -0
  24. package/dist/runtime/app/pages/id-code.vue.d.ts +3 -0
  25. package/dist/runtime/app/pages/layout.d.vue.ts +3 -0
  26. package/dist/runtime/app/pages/layout.vue +10 -0
  27. package/dist/runtime/app/pages/layout.vue.d.ts +3 -0
  28. package/dist/runtime/app/pages/profile.vue +188 -46
  29. package/dist/runtime/app/pages/security.vue +180 -60
  30. package/dist/runtime/app/utils/documents.d.ts +5 -0
  31. package/dist/runtime/app/utils/documents.js +7 -0
  32. package/dist/runtime/i18n/lang/da.json +125 -13
  33. package/dist/runtime/i18n/lang/en.json +125 -13
  34. package/dist/runtime/menus.js +36 -0
  35. package/dist/runtime/server/routes/account/id-code.get.js +20 -0
  36. package/package.json +22 -10
  37. package/dist/runtime/server/db/schema.sqlite.d.ts +0 -24
  38. package/dist/runtime/server/db/schema.sqlite.js +0 -4
  39. package/dist/runtime/server/routes/account/change-email.post.js +0 -20
  40. package/dist/runtime/server/routes/account/change-password.post.d.ts +0 -2
  41. package/dist/runtime/server/routes/account/change-password.post.js +0 -26
  42. package/dist/runtime/server/routes/account/profile.post.d.ts +0 -2
  43. package/dist/runtime/server/routes/account/profile.post.js +0 -17
  44. /package/dist/runtime/server/routes/account/{change-email.post.d.ts → id-code.get.d.ts} +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @frigear-nu/account
2
2
 
3
- A module for the account area (profile, email, password, security) in the main frigear app. Migrated from
3
+ A module for the account area (profile, security, documents, API tokens pages) in the main frigear app. Migrated from
4
4
  [`nuxt-frigear-nu`](https://github.com/Frigear-nu/nuxt-frigear-nu)'s `app/pages/account/**`.
5
5
 
6
6
  ## Features
@@ -8,13 +8,13 @@ A module for the account area (profile, email, password, security) in the main f
8
8
  - 👤 Update your profile details (name, avatar).
9
9
  - ✉️ Change your email address.
10
10
  - 🔒 Change your password.
11
- - 🔑 Manage passkeys (via `@frigear-nu/users`' `useUserPasskeys`, when WebAuthn is enabled there).
11
+ - 🔑 Manage passkeys (via `@frigear-nu/auth`'s `usePasskeys`, when WebAuthn is enabled there).
12
12
  - 🧩 Overridable composable (`useAccount`) and opt-in profile/security pages (built with [`@nuxt/ui`](https://ui.nuxt.com)).
13
13
  - 🗂️ Contributes "Profile"/"Security" tiles to `@frigear-nu/menu` (when installed), and an opt-in dashboard page
14
14
  listing them.
15
15
 
16
- This module reuses `@frigear-nu/users`' session/password utilities instead of registering its own `users` database
17
- table or duplicating auth logic - it only adds the account-management routes that didn't already exist there.
16
+ This module is a UI shell: it owns no tables and no mutation routes. The forms call the self-service routes of
17
+ `@frigear-nu/users` (`/api/users/me/*`) and the token routes of `@frigear-nu/auth`.
18
18
 
19
19
  ## Quick Setup
20
20
 
@@ -24,8 +24,8 @@ Install the module to your Nuxt application with one command:
24
24
  npx nuxt module add @frigear-nu/account
25
25
  ```
26
26
 
27
- This module requires [`@frigear-nu/users`](../users) to be installed in the host app, since it updates the same
28
- `users` database table and reuses its session helpers (`mapUserToSession`, `hashPassword`/`verifyPassword`).
27
+ This module requires [`@frigear-nu/users`](../users) to be installed in the host app, since its forms call the
28
+ self-service routes there.
29
29
 
30
30
  ## Configuration
31
31
 
@@ -74,3 +74,12 @@ await changePassword({ currentPassword: 'old', newPassword: 'new-password', conf
74
74
 
75
75
  Strings live under the `account.*` namespace in `da`/`en` locale files and can be overridden in your app's
76
76
  `i18n/locales/<code>.json`. See the [documentation](https://docs.frigear.dev/modules/account#translations).
77
+
78
+ ## Frigear ID (QR code)
79
+
80
+ `settings.pages.idCode` (`true` or a path, default `/account/id`) adds a page with a QR code (`urn:frigear:id:<jwt>`)
81
+ that refreshes every 60 seconds, plus an account menu tile. `GET /api/account/id-code` returns the RS256-signed JWT
82
+ (60s lifetime, `sub` = user id). It signs with `runtimeConfig.account.idCode.privateKey`
83
+ (`NUXT_ACCOUNT_ID_CODE_PRIVATE_KEY`) or, when unset, the `@frigear-nu/oauth-server` key (`runtimeConfig.oauthServer`),
84
+ so scanners can verify it against `/.well-known/jwks.json`. Without a key the endpoint responds `501`.
85
+ `AccountIdentificationCodeDialog` wraps the same content in a modal.
package/dist/module.d.mts CHANGED
@@ -1,11 +1,29 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
2
 
3
+ /** A downloadable file listed on the documents page. */
4
+ type AccountDocument = {
5
+ id: string;
6
+ /** A string, or a map of locale -> string (falls back to `en`, then the first value). */
7
+ label: string | Record<string, string>;
8
+ /** Where the file is served from, e.g. `/assets/files/handbook.pdf`. */
9
+ path: string;
10
+ icon?: string;
11
+ /**
12
+ * Only shown to users with one of these roles (the `role` of the session user). Omit to show to every signed-in
13
+ * user. This only decides what is *listed*: a file in `public/` can still be fetched by anyone who knows its URL.
14
+ */
15
+ roles?: string[];
16
+ };
3
17
  type PublicModuleOptions = {
4
18
  pages: {
5
19
  index?: string;
6
20
  profile?: string;
7
21
  security?: string;
22
+ documents?: string;
23
+ idCode?: string;
24
+ apiTokens?: string;
8
25
  };
26
+ documents: AccountDocument[];
9
27
  };
10
28
  type ModuleOptions = {
11
29
  settings?: {
@@ -13,7 +31,11 @@ type ModuleOptions = {
13
31
  index?: string | boolean;
14
32
  profile?: string | boolean;
15
33
  security?: string | boolean;
34
+ documents?: string | boolean;
35
+ idCode?: string | boolean;
36
+ apiTokens?: string | boolean;
16
37
  };
38
+ documents?: AccountDocument[];
17
39
  };
18
40
  };
19
41
 
@@ -21,6 +43,15 @@ declare module 'nuxt/schema' {
21
43
  interface NuxtConfig {
22
44
  account?: ModuleOptions;
23
45
  }
46
+ interface RuntimeConfig {
47
+ account?: {
48
+ idCode?: {
49
+ privateKey?: string;
50
+ keyId?: string;
51
+ issuer?: string;
52
+ };
53
+ };
54
+ }
24
55
  interface PublicRuntimeConfig {
25
56
  account?: PublicModuleOptions;
26
57
  }
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@frigear-nu/account",
3
3
  "configKey": "account",
4
- "version": "0.0.7",
4
+ "version": "0.0.8",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.3",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -1,11 +1,6 @@
1
1
  import { defineNuxtModule, createResolver, hasNuxtModule, addServerHandler, addImports, extendPages, addComponentsDir } from '@nuxt/kit';
2
- import { registerModule, registerLocales, extendDatabaseTable } from '@frigear-nu/module-kit/utils';
2
+ import { registerModule, registerTailwindSource, registerLocales, resolvePagePath, addOptionalMenuSource } from '@frigear-nu/module-kit/utils';
3
3
 
4
- function resolvePagePath(setting, defaultPath) {
5
- if (typeof setting === "string") return setting;
6
- if (setting === true) return defaultPath;
7
- return void 0;
8
- }
9
4
  const module$1 = defineNuxtModule({
10
5
  meta: { name: "@frigear-nu/account", configKey: "account" },
11
6
  defaults: {
@@ -18,6 +13,8 @@ const module$1 = defineNuxtModule({
18
13
  "@frigear-nu/module-kit": {
19
14
  version: ">=0.0.1"
20
15
  },
16
+ "@frigear-nu/auth": { version: ">=0.0.1" },
17
+ // The profile, email and password forms call its self-service routes.
21
18
  "@frigear-nu/users": {
22
19
  version: ">=0.0.1"
23
20
  },
@@ -29,59 +26,67 @@ const module$1 = defineNuxtModule({
29
26
  async setup(options, nuxt) {
30
27
  registerModule("@frigear-nu/account", nuxt);
31
28
  const resolver = createResolver(import.meta.url);
29
+ registerTailwindSource(nuxt, resolver.resolve("./runtime/app"));
32
30
  registerLocales(nuxt, resolver.resolve("./runtime/i18n/lang"));
33
31
  const settings = options.settings ?? {};
34
32
  const withMenus = hasNuxtModule("@frigear-nu/menu");
35
33
  addServerHandler({
36
- route: "/api/account/profile",
37
- method: "post",
38
- handler: resolver.resolve("./runtime/server/routes/account/profile.post")
39
- });
40
- addServerHandler({
41
- route: "/api/account/change-email",
42
- method: "post",
43
- handler: resolver.resolve("./runtime/server/routes/account/change-email.post")
44
- });
45
- addServerHandler({
46
- route: "/api/account/change-password",
47
- method: "post",
48
- handler: resolver.resolve("./runtime/server/routes/account/change-password.post")
34
+ route: "/api/account/id-code",
35
+ method: "get",
36
+ handler: resolver.resolve("./runtime/server/routes/account/id-code.get")
49
37
  });
38
+ const existingAccount = nuxt.options.runtimeConfig.account;
39
+ nuxt.options.runtimeConfig.account = {
40
+ idCode: { privateKey: "", keyId: "", issuer: "", ...existingAccount?.idCode }
41
+ };
50
42
  addImports([{ name: "useAccount", from: resolver.resolve("./runtime/app/composables/useAccount") }]);
51
43
  const profilePath = resolvePagePath(settings.pages?.profile, "/account/profile");
52
44
  const securityPath = resolvePagePath(settings.pages?.security, "/account/security");
45
+ const documentsPath = resolvePagePath(settings.pages?.documents, "/account/documents");
46
+ const idCodePath = resolvePagePath(settings.pages?.idCode, "/account/id");
47
+ const apiTokensPath = resolvePagePath(settings.pages?.apiTokens, "/account/api-tokens");
53
48
  const indexPath = withMenus ? resolvePagePath(settings.pages?.index, "/account") : void 0;
54
49
  if (!withMenus && settings.pages?.index) {
55
50
  console.warn("[@frigear-nu/account] `settings.pages.index` was set, but `@frigear-nu/menu` is not installed - skipping the dashboard page.");
56
51
  }
57
52
  nuxt.options.runtimeConfig.public.account = {
58
- pages: { index: indexPath, profile: profilePath, security: securityPath }
53
+ pages: { index: indexPath, profile: profilePath, security: securityPath, documents: documentsPath, idCode: idCodePath, apiTokens: apiTokensPath },
54
+ documents: settings.documents ?? []
59
55
  };
60
- if (indexPath || profilePath || securityPath) {
56
+ if (indexPath || profilePath || securityPath || documentsPath || idCodePath || apiTokensPath) {
61
57
  extendPages((pages) => {
62
58
  const existingPaths = new Set(pages.map((page) => page.path));
63
- if (indexPath && !existingPaths.has(indexPath)) {
64
- pages.push({ name: "account-index", path: indexPath, file: resolver.resolve("./runtime/app/pages/index.vue") });
65
- }
66
- if (profilePath && !existingPaths.has(profilePath)) {
67
- pages.push({ name: "account-profile", path: profilePath, file: resolver.resolve("./runtime/app/pages/profile.vue") });
68
- }
69
- if (securityPath && !existingPaths.has(securityPath)) {
70
- pages.push({ name: "account-security", path: securityPath, file: resolver.resolve("./runtime/app/pages/security.vue") });
59
+ const children = [];
60
+ const add = (path, name, file) => {
61
+ if (path && !existingPaths.has(path)) children.push({ name, path, file: resolver.resolve(file) });
62
+ };
63
+ add(indexPath, "account-index", "./runtime/app/pages/index.vue");
64
+ add(profilePath, "account-profile", "./runtime/app/pages/profile.vue");
65
+ add(documentsPath, "account-documents", "./runtime/app/pages/documents.vue");
66
+ add(securityPath, "account-security", "./runtime/app/pages/security.vue");
67
+ add(idCodePath, "account-id-code", "./runtime/app/pages/id-code.vue");
68
+ add(apiTokensPath, "account-api-tokens", "./runtime/app/pages/api-tokens.vue");
69
+ if (children.length) {
70
+ pages.push({ name: "account-layout", path: "/__account", file: resolver.resolve("./runtime/app/pages/layout.vue"), children });
71
71
  }
72
72
  });
73
73
  }
74
- if (withMenus) {
75
- const { registerMenuSource } = await import('@frigear-nu/menu/utils');
76
- registerMenuSource(nuxt, { file: resolver.resolve("./runtime/menus"), menu: "dashboard.account" });
74
+ if (hasNuxtModule("@frigear-nu/authorization")) {
75
+ const prefixes = ["", ...(nuxt.options.i18n?.locales ?? []).map((locale) => typeof locale === "string" ? locale : locale.code).map((code) => `/${code}`)];
76
+ const rules = nuxt.options.routeRules ||= {};
77
+ const guarded = [indexPath, profilePath, securityPath, documentsPath, idCodePath, apiTokensPath].filter((path) => !!path && !path.startsWith("/account"));
78
+ for (const prefix of prefixes) {
79
+ for (const pattern of [`${prefix}/account`, `${prefix}/account/**`, ...guarded.map((path) => `${prefix}${path}`)]) {
80
+ rules[pattern] = { authenticated: true, ...rules[pattern] };
81
+ }
82
+ }
83
+ } else {
84
+ console.warn("[@frigear-nu/account] @frigear-nu/authorization is not installed: the account pages are not guarded. Install it and guard `/account/**` yourself.");
77
85
  }
86
+ addOptionalMenuSource(nuxt, { file: resolver.resolve("./runtime/menus"), menu: "dashboard.account" });
78
87
  addComponentsDir({
79
88
  path: resolver.resolve("./runtime/app/components")
80
89
  });
81
- extendDatabaseTable(nuxt, {
82
- resolver,
83
- file: (dialect) => `./runtime/server/db/schema.${dialect}`
84
- });
85
90
  }
86
91
  });
87
92
 
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,59 @@
1
+ <script setup>
2
+ const t = useModuleT("account");
3
+ const route = useRoute();
4
+ const { user } = useUserSession();
5
+ const pages = useRuntimeConfig().public.account?.pages;
6
+ const nuxtApp = useNuxtApp();
7
+ const items = typeof useMenu === "function" ? useMenu("account").data : ref([]);
8
+ const trimSlash = (path) => path.length > 1 ? path.replace(/\/+$/, "") : path;
9
+ const stripLocale = (path) => {
10
+ const trimmed = trimSlash(path);
11
+ const first = trimmed.split("/")[1];
12
+ const codes = (nuxtApp.$i18n?.locales?.value ?? []).map((locale) => typeof locale === "string" ? locale : locale.code);
13
+ return first && codes.includes(first) ? trimmed.slice(first.length + 1) || "/" : trimmed;
14
+ };
15
+ const current = computed(() => {
16
+ const path = stripLocale(route.path);
17
+ return (items.value ?? []).find((item) => item.to && !item.external && stripLocale(item.to) === path);
18
+ });
19
+ const title = computed(() => current.value?.label ?? t("title", "Account"));
20
+ const description = computed(() => current.value?.description);
21
+ </script>
22
+
23
+ <template>
24
+ <UContainer>
25
+ <UPageHeader
26
+ :title="title"
27
+ :description="description"
28
+ :ui="{ wrapper: 'flex-row items-center justify-between gap-4', description: 'mt-2' }"
29
+ >
30
+ <UButton
31
+ v-if="current && pages?.index"
32
+ variant="link"
33
+ icon="i-lucide-arrow-left"
34
+ :to="pages.index"
35
+ :label="t('backTo', 'Back to account')"
36
+ class="-ml-3 mt-2"
37
+ />
38
+
39
+ <template #links>
40
+ <div
41
+ v-if="user"
42
+ class="flex flex-col"
43
+ >
44
+ <div class="text-sm text-muted">
45
+ {{ t("signedInAs", "Signed in as") }}
46
+ </div>
47
+ <div class="text-primary">
48
+ {{ user.email }}
49
+ </div>
50
+ <div class="mt-1 flex justify-end">
51
+ <UBadge variant="soft">
52
+ Frigear ID: <code>{{ user.id }}</code>
53
+ </UBadge>
54
+ </div>
55
+ </div>
56
+ </template>
57
+ </UPageHeader>
58
+ </UContainer>
59
+ </template>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -19,13 +19,18 @@ const items = computedAsync(async () => {
19
19
  }
20
20
  ]);
21
21
  }
22
- items2.push(dropdownItems.value?.map((item) => ({
22
+ const role = user.value?.role;
23
+ const visible = (dropdownItems.value ?? []).filter((item) => {
24
+ const roles = item.meta?.roles;
25
+ return !roles?.length || !!role && roles.includes(role);
26
+ });
27
+ items2.push(visible.map((item) => ({
23
28
  label: item.label,
24
29
  to: item.to,
25
30
  icon: item.icon,
26
31
  external: item.external,
27
32
  replace: item.external
28
- })) || []);
33
+ })));
29
34
  return items2;
30
35
  });
31
36
  </script>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,82 @@
1
+ <script setup>
2
+ import { renderSVG } from "uqr";
3
+ import { useIntervalFn } from "@vueuse/core";
4
+ const t = useModuleT("account.identificationCode");
5
+ const { user } = useUserSession();
6
+ const { data, refresh, status, error } = useFetch("/api/account/id-code", { server: false });
7
+ const remaining = ref(0);
8
+ watch(data, (value) => {
9
+ remaining.value = value?.expiresIn ?? 0;
10
+ }, { immediate: true });
11
+ const refreshing = computed(() => status.value === "pending");
12
+ useIntervalFn(() => {
13
+ if (!data.value || refreshing.value) return;
14
+ if (remaining.value <= 1) {
15
+ remaining.value = 0;
16
+ refresh();
17
+ return;
18
+ }
19
+ remaining.value -= 1;
20
+ }, 1e3);
21
+ const svg = computed(() => data.value ? renderSVG(data.value.payload, { ecc: "L", border: 1 }) : "");
22
+ const role = computed(() => user.value?.role);
23
+ const membership = computed(() => user.value?.membership);
24
+ </script>
25
+
26
+ <template>
27
+ <div class="flex flex-col items-center gap-3">
28
+ <UAlert
29
+ v-if="error"
30
+ color="error"
31
+ variant="subtle"
32
+ icon="i-lucide-triangle-alert"
33
+ :title="t('error', 'Could not create your Frigear ID.')"
34
+ />
35
+ <template v-else-if="svg">
36
+ <!-- eslint-disable-next-line vue/no-v-html -->
37
+ <div
38
+ class="size-60 rounded-md bg-white p-2 [&>svg]:size-full"
39
+ v-html="svg"
40
+ />
41
+ <UBadge
42
+ color="warning"
43
+ class="text-xl font-bold"
44
+ >
45
+ {{ t("expiresIn", "Refreshes in {time}s").replace("{time}", String(remaining)) }}
46
+ </UBadge>
47
+ <div class="flex flex-wrap justify-center gap-2">
48
+ <UBadge
49
+ v-if="user"
50
+ size="lg"
51
+ >
52
+ Frigear ID: {{ user.id }}
53
+ </UBadge>
54
+ <UBadge
55
+ v-if="membership"
56
+ size="lg"
57
+ >
58
+ {{ membership }}
59
+ </UBadge>
60
+ <UBadge
61
+ v-if="role"
62
+ size="lg"
63
+ color="success"
64
+ >
65
+ {{ t("role", "Role") }}: {{ role }}
66
+ </UBadge>
67
+ </div>
68
+ </template>
69
+ <UIcon
70
+ v-else
71
+ name="i-lucide-refresh-cw"
72
+ class="size-6 animate-spin"
73
+ />
74
+ <UButton
75
+ icon="i-lucide-refresh-cw"
76
+ variant="subtle"
77
+ :loading="refreshing"
78
+ :label="t('refresh', 'Refresh')"
79
+ @click="refresh()"
80
+ />
81
+ </div>
82
+ </template>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,20 @@
1
+ type __VLS_ModelProps = {
2
+ 'open'?: boolean;
3
+ };
4
+ declare var __VLS_8: {};
5
+ type __VLS_Slots = {} & {
6
+ default?: (props: typeof __VLS_8) => any;
7
+ };
8
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ "update:open": (value: boolean) => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
11
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
12
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
16
+ type __VLS_WithSlots<T, S> = T & {
17
+ new (): {
18
+ $slots: S;
19
+ };
20
+ };
@@ -0,0 +1,16 @@
1
+ <script setup>
2
+ const t = useModuleT("account.identificationCode");
3
+ const open = defineModel("open", { type: Boolean, ...{ default: false } });
4
+ </script>
5
+
6
+ <template>
7
+ <UModal
8
+ v-model:open="open"
9
+ :title="t('title', 'Frigear ID')"
10
+ >
11
+ <slot />
12
+ <template #body>
13
+ <AccountIdentificationCode v-if="open" />
14
+ </template>
15
+ </UModal>
16
+ </template>
@@ -0,0 +1,20 @@
1
+ type __VLS_ModelProps = {
2
+ 'open'?: boolean;
3
+ };
4
+ declare var __VLS_8: {};
5
+ type __VLS_Slots = {} & {
6
+ default?: (props: typeof __VLS_8) => any;
7
+ };
8
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ "update:open": (value: boolean) => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
11
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
12
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
16
+ type __VLS_WithSlots<T, S> = T & {
17
+ new (): {
18
+ $slots: S;
19
+ };
20
+ };
@@ -17,19 +17,19 @@ export const useAccount = () => {
17
17
  }
18
18
  function updateProfileDetails(payload) {
19
19
  return withRequest(
20
- () => $fetch("/api/account/profile", { method: "POST", body: payload }),
20
+ () => $fetch("/api/users/me/profile", { method: "POST", body: payload }),
21
21
  "Failed to update your profile."
22
22
  );
23
23
  }
24
24
  function changeEmailAddress(payload) {
25
25
  return withRequest(
26
- () => $fetch("/api/account/change-email", { method: "POST", body: payload }),
26
+ () => $fetch("/api/users/me/change-email", { method: "POST", body: payload }),
27
27
  "Failed to change your email address."
28
28
  );
29
29
  }
30
30
  function changePassword(payload) {
31
31
  return withRequest(
32
- () => $fetch("/api/account/change-password", { method: "POST", body: payload }),
32
+ () => $fetch("/api/users/me/change-password", { method: "POST", body: payload }),
33
33
  "Failed to change your password."
34
34
  );
35
35
  }
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;