@frigear-nu/account 0.0.7 → 0.0.9

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 (37) hide show
  1. package/README.md +11 -6
  2. package/dist/module.d.mts +20 -0
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +35 -40
  5. package/dist/runtime/app/components/Account/AccountHeader.d.vue.ts +3 -0
  6. package/dist/runtime/app/components/Account/AccountHeader.vue +43 -0
  7. package/dist/runtime/app/components/Account/AccountHeader.vue.d.ts +3 -0
  8. package/dist/runtime/app/components/Account/AccountHeaderRight.d.vue.ts +3 -0
  9. package/dist/runtime/app/components/Account/AccountHeaderRight.vue +18 -0
  10. package/dist/runtime/app/components/Account/AccountHeaderRight.vue.d.ts +3 -0
  11. package/dist/runtime/app/components/Account/AccountMenu.vue +7 -2
  12. package/dist/runtime/app/composables/useAccount.js +3 -3
  13. package/dist/runtime/app/pages/api-tokens.d.vue.ts +3 -0
  14. package/dist/runtime/app/pages/api-tokens.vue +308 -0
  15. package/dist/runtime/app/pages/api-tokens.vue.d.ts +3 -0
  16. package/dist/runtime/app/pages/documents.d.vue.ts +3 -0
  17. package/dist/runtime/app/pages/documents.vue +38 -0
  18. package/dist/runtime/app/pages/documents.vue.d.ts +3 -0
  19. package/dist/runtime/app/pages/layout.d.vue.ts +3 -0
  20. package/dist/runtime/app/pages/layout.vue +10 -0
  21. package/dist/runtime/app/pages/layout.vue.d.ts +3 -0
  22. package/dist/runtime/app/pages/profile.vue +188 -46
  23. package/dist/runtime/app/pages/security.vue +180 -60
  24. package/dist/runtime/app/utils/documents.d.ts +5 -0
  25. package/dist/runtime/app/utils/documents.js +7 -0
  26. package/dist/runtime/i18n/lang/da.json +120 -16
  27. package/dist/runtime/i18n/lang/en.json +120 -16
  28. package/dist/runtime/menus.js +24 -0
  29. package/package.json +20 -10
  30. package/dist/runtime/server/db/schema.sqlite.d.ts +0 -24
  31. package/dist/runtime/server/db/schema.sqlite.js +0 -4
  32. package/dist/runtime/server/routes/account/change-email.post.d.ts +0 -2
  33. package/dist/runtime/server/routes/account/change-email.post.js +0 -20
  34. package/dist/runtime/server/routes/account/change-password.post.d.ts +0 -2
  35. package/dist/runtime/server/routes/account/change-password.post.js +0 -26
  36. package/dist/runtime/server/routes/account/profile.post.d.ts +0 -2
  37. package/dist/runtime/server/routes/account/profile.post.js +0 -17
@@ -14,38 +14,56 @@
14
14
  "security": {
15
15
  "label": "Sikkerhed",
16
16
  "description": "Skift din adgangskode og administrer adgangsnøgler."
17
+ },
18
+ "documents": {
19
+ "label": "Dokumenter",
20
+ "description": "Håndbøger og andre filer til dig."
21
+ },
22
+ "apiTokens": {
23
+ "label": "API-nøgler",
24
+ "description": "Opret nøgler til scripts og værktøjer."
17
25
  }
18
26
  },
19
- "identificationCode": {
20
- "title": "Frigear ID",
21
- "description": "Tryk her for at vise dit ID."
22
- },
23
27
  "profile": {
24
28
  "title": "Profil",
25
29
  "description": "Skift dine brugeroplysninger.",
26
30
  "name": {
27
31
  "label": "Navn",
28
- "description": "Dit fulde navn."
32
+ "description": "Dit fulde navn.",
33
+ "required": "Indtast dit navn."
29
34
  },
30
35
  "email": {
31
36
  "label": "E-mail",
32
37
  "description": "Din awesome e-mail.",
33
38
  "change": {
34
39
  "title": "Skift din e-mail",
35
- "label": "Ny e-mail"
36
- }
40
+ "label": "Ny e-mail",
41
+ "sent": {
42
+ "title": "Tjek din indbakke",
43
+ "description": "Vi har sendt et link til din nye adresse. Ændringen træder først i kraft når du bekræfter den."
44
+ },
45
+ "done": "Din e-mailadresse er ændret.",
46
+ "failed": "Bekræftelseslinket er ugyldigt eller udløbet.",
47
+ "error": "Kunne ikke ændre din e-mailadresse."
48
+ },
49
+ "invalid": "Indtast en gyldig e-mailadresse."
37
50
  },
38
51
  "avatar": {
39
52
  "label": "Avatar",
40
- "description": "JPG, GIF eller PNG. 1MB Max.",
41
- "url": "Avatar URL"
53
+ "description": "Link til et kvadratisk billede.",
54
+ "url": "Avatar URL",
55
+ "invalid": "Indtast en gyldig URL."
42
56
  },
43
- "save": "Gem profil"
57
+ "save": "Gem profil",
58
+ "saved": "Profil opdateret",
59
+ "saveFailed": "Kunne ikke opdatere din profil.",
60
+ "cancel": "Annuller"
44
61
  },
45
62
  "documents": {
46
63
  "title": "Dokumenter",
47
64
  "description": "Dine dokumenter.",
48
- "download": "Download"
65
+ "download": "Download",
66
+ "empty": "Ingen dokumenter til dig endnu."
49
67
  },
50
68
  "security": {
51
69
  "title": "Sikkerhed",
@@ -58,19 +76,105 @@
58
76
  "title": "Skift password",
59
77
  "submit": "Skift password",
60
78
  "new": {
61
- "label": "Nyt password"
79
+ "label": "Nyt password",
80
+ "min": "Brug mindst 8 tegn."
62
81
  },
63
82
  "confirm": {
64
- "label": "Bekræft nyt password"
83
+ "label": "Bekræft nyt password",
84
+ "mismatch": "Passwords er ikke ens."
65
85
  },
66
86
  "current": {
67
- "label": "Nuværende password"
68
- }
87
+ "label": "Nuværende password",
88
+ "required": "Indtast dit nuværende password."
89
+ },
90
+ "success": "Dit password er skiftet.",
91
+ "error": "Kunne ikke skifte dit password."
69
92
  },
70
93
  "passkeys": {
71
94
  "title": "Passkeys",
72
- "register": "Registrér en passkey"
95
+ "register": "Registrér en passkey",
96
+ "description": "Log ind med fingeraftryk, ansigt eller enhedens pinkode i stedet for et password.",
97
+ "unnamed": "Passkey",
98
+ "created": "Tilføjet {date}",
99
+ "remove": "Fjern passkey",
100
+ "empty": "Du har ikke tilføjet nogen passkeys endnu.",
101
+ "name": {
102
+ "label": "Navn på passkey",
103
+ "placeholder": "Navn, fx MacBook"
104
+ },
105
+ "registered": "Passkey tilføjet.",
106
+ "registerError": "Kunne ikke registrere passkey.",
107
+ "removed": "Passkey fjernet.",
108
+ "removeError": "Kunne ikke fjerne passkey.",
109
+ "loadError": "Kunne ikke hente dine passkeys."
73
110
  }
111
+ },
112
+ "backTo": "Tilbage til konto",
113
+ "signedInAs": "Logget ind som",
114
+ "apiTokens": {
115
+ "title": "API-nøgler",
116
+ "description": "Opret nøgler til scripts og værktøjer.",
117
+ "allScopes": "Fuld adgang",
118
+ "copy": "Kopiér",
119
+ "copied": "Nøglen er kopieret.",
120
+ "copiedSnippet": "Kopieret.",
121
+ "copyError": "Kunne ikke kopiere. Markér nøglen og kopiér den manuelt.",
122
+ "create": {
123
+ "title": "Opret en API-nøgle",
124
+ "description": "Nøgler lader scripts og værktøjer som MCP-klienter handle på dine vegne. Giv hver nøgle kun de rettigheder, den har brug for.",
125
+ "submit": "Opret nøgle"
126
+ },
127
+ "createError": "Kunne ikke oprette nøglen.",
128
+ "name": {
129
+ "label": "Navn",
130
+ "placeholder": "fx Min MCP-klient",
131
+ "required": "Giv nøglen et navn."
132
+ },
133
+ "scopes": {
134
+ "label": "Rettigheder",
135
+ "placeholder": "Vælg hvad nøglen må",
136
+ "required": "Vælg mindst én rettighed."
137
+ },
138
+ "expiry": {
139
+ "label": "Udløber",
140
+ "30": "30 dage",
141
+ "90": "90 dage",
142
+ "365": "1 år",
143
+ "never": "Udløber aldrig"
144
+ },
145
+ "reveal": {
146
+ "title": "Kopiér din nye nøgle nu",
147
+ "description": "Det er eneste gang, den vises. Mister du den, skal du oprette en ny.",
148
+ "label": "Ny nøgle",
149
+ "done": "Færdig"
150
+ },
151
+ "connect": {
152
+ "title": "Forbind til MCP",
153
+ "description": "Brug din konto fra en AI-assistent. Din API-nøgle indsættes kun i kommandoerne lige efter, du har oprettet den.",
154
+ "claude": {
155
+ "steps": "Claude.ai og Claude Desktop: åbn Indstillinger → Connectors → Tilføj brugerdefineret connector, indsæt URL'en nedenfor og log ind, når du bliver bedt om det. Ingen nøgle nødvendig.",
156
+ "cli": "Claude Code (bruger en API-nøgle):"
157
+ },
158
+ "chatgpt": {
159
+ "steps": "ChatGPT: åbn Indstillinger → Connectors → Avanceret, slå udviklertilstand til, og opret en connector med URL'en nedenfor. Vælg OAuth og log ind, når du bliver bedt om det. Ingen nøgle nødvendig."
160
+ }
161
+ },
162
+ "list": {
163
+ "title": "Dine nøgler",
164
+ "description": "Træk en nøgle tilbage for at stoppe den med det samme.",
165
+ "empty": "Du har ikke oprettet nogen nøgler endnu.",
166
+ "created": "Oprettet {date}",
167
+ "lastUsed": "Sidst brugt {date}",
168
+ "expires": "Udløber {date}"
169
+ },
170
+ "status": {
171
+ "ok": "Aktiv",
172
+ "revoked": "Trukket tilbage",
173
+ "expired": "Udløbet"
174
+ },
175
+ "revoke": "Træk nøgle tilbage",
176
+ "revoked": "Nøglen er trukket tilbage.",
177
+ "revokeError": "Kunne ikke trække nøglen tilbage."
74
178
  }
75
179
  }
76
180
  }
@@ -14,38 +14,56 @@
14
14
  "security": {
15
15
  "label": "Security",
16
16
  "description": "Change your password and manage passkeys."
17
+ },
18
+ "documents": {
19
+ "label": "Documents",
20
+ "description": "Handbooks and other files for you."
21
+ },
22
+ "apiTokens": {
23
+ "label": "API tokens",
24
+ "description": "Create tokens for scripts and tools."
17
25
  }
18
26
  },
19
- "identificationCode": {
20
- "title": "Frigear ID",
21
- "description": "Press here to show your ID."
22
- },
23
27
  "profile": {
24
28
  "title": "Profile",
25
29
  "description": "Change your information.",
26
30
  "name": {
27
31
  "label": "Name",
28
- "description": "Your full name."
32
+ "description": "Your full name.",
33
+ "required": "Please enter your name."
29
34
  },
30
35
  "email": {
31
36
  "label": "E-mail",
32
37
  "description": "Your awesome E-mail.",
33
38
  "change": {
34
39
  "title": "Change e-mail",
35
- "label": "New e-mail"
36
- }
40
+ "label": "New e-mail",
41
+ "sent": {
42
+ "title": "Check your inbox",
43
+ "description": "We sent a link to your new address. It takes effect once you confirm it."
44
+ },
45
+ "done": "Your email address was changed.",
46
+ "failed": "This confirmation link is invalid or has expired.",
47
+ "error": "Could not change your email address."
48
+ },
49
+ "invalid": "Enter a valid email address."
37
50
  },
38
51
  "avatar": {
39
52
  "label": "Avatar",
40
- "description": "JPG, GIF or PNG. 1MB Max.",
41
- "url": "Avatar URL"
53
+ "description": "Link to a square image.",
54
+ "url": "Avatar URL",
55
+ "invalid": "Enter a valid URL."
42
56
  },
43
- "save": "Save profile"
57
+ "save": "Save profile",
58
+ "saved": "Profile updated",
59
+ "saveFailed": "Could not update your profile.",
60
+ "cancel": "Cancel"
44
61
  },
45
62
  "documents": {
46
63
  "title": "Documents",
47
64
  "description": "Your documents.",
48
- "download": "Download"
65
+ "download": "Download",
66
+ "empty": "No documents for you yet."
49
67
  },
50
68
  "security": {
51
69
  "title": "Security",
@@ -58,19 +76,105 @@
58
76
  "title": "Change password",
59
77
  "submit": "Change password",
60
78
  "new": {
61
- "label": "New password"
79
+ "label": "New password",
80
+ "min": "Use at least 8 characters."
62
81
  },
63
82
  "confirm": {
64
- "label": "Confirm new password"
83
+ "label": "Confirm new password",
84
+ "mismatch": "The passwords do not match."
65
85
  },
66
86
  "current": {
67
- "label": "Current password"
68
- }
87
+ "label": "Current password",
88
+ "required": "Enter your current password."
89
+ },
90
+ "success": "Your password was changed.",
91
+ "error": "Could not change your password."
69
92
  },
70
93
  "passkeys": {
71
94
  "title": "Passkeys",
72
- "register": "Register a passkey"
95
+ "register": "Register a passkey",
96
+ "description": "Sign in with your fingerprint, face or device PIN instead of a password.",
97
+ "unnamed": "Passkey",
98
+ "created": "Added {date}",
99
+ "remove": "Remove passkey",
100
+ "empty": "You have not added any passkeys yet.",
101
+ "name": {
102
+ "label": "Passkey name",
103
+ "placeholder": "Name, e.g. MacBook"
104
+ },
105
+ "registered": "Passkey added.",
106
+ "registerError": "Could not register the passkey.",
107
+ "removed": "Passkey removed.",
108
+ "removeError": "Could not remove the passkey.",
109
+ "loadError": "Could not load your passkeys."
73
110
  }
111
+ },
112
+ "backTo": "Back to account",
113
+ "signedInAs": "Signed in as",
114
+ "apiTokens": {
115
+ "title": "API tokens",
116
+ "description": "Create tokens for scripts and tools.",
117
+ "allScopes": "Full access",
118
+ "copy": "Copy",
119
+ "copied": "Token copied.",
120
+ "copiedSnippet": "Copied.",
121
+ "copyError": "Could not copy. Select the token and copy it manually.",
122
+ "create": {
123
+ "title": "Create an API token",
124
+ "description": "Tokens let scripts and tools such as MCP clients act as you. Give each one only the scopes it needs.",
125
+ "submit": "Create token"
126
+ },
127
+ "createError": "Could not create the token.",
128
+ "name": {
129
+ "label": "Name",
130
+ "placeholder": "e.g. My MCP client",
131
+ "required": "Give the token a name."
132
+ },
133
+ "scopes": {
134
+ "label": "Scopes",
135
+ "placeholder": "Choose what the token may do",
136
+ "required": "Pick at least one scope."
137
+ },
138
+ "expiry": {
139
+ "label": "Expires",
140
+ "30": "30 days",
141
+ "90": "90 days",
142
+ "365": "1 year",
143
+ "never": "No expiry"
144
+ },
145
+ "reveal": {
146
+ "title": "Copy your new token now",
147
+ "description": "This is the only time it is shown. If you lose it, create a new one.",
148
+ "label": "New token",
149
+ "done": "Done"
150
+ },
151
+ "connect": {
152
+ "title": "Connect to MCP",
153
+ "description": "Use your account from an AI assistant. Your API token is only filled into the commands right after you create it.",
154
+ "claude": {
155
+ "steps": "Claude.ai and Claude Desktop: open Settings → Connectors → Add custom connector, paste the URL below and sign in when asked. No token needed.",
156
+ "cli": "Claude Code (uses an API token):"
157
+ },
158
+ "chatgpt": {
159
+ "steps": "ChatGPT: open Settings → Connectors → Advanced, turn on Developer mode, then create a connector with the URL below. Choose OAuth and sign in when asked. No token needed."
160
+ }
161
+ },
162
+ "list": {
163
+ "title": "Your tokens",
164
+ "description": "Revoke a token to stop it working immediately.",
165
+ "empty": "You have not created any tokens yet.",
166
+ "created": "Created {date}",
167
+ "lastUsed": "Last used {date}",
168
+ "expires": "Expires {date}"
169
+ },
170
+ "status": {
171
+ "ok": "Active",
172
+ "revoked": "Revoked",
173
+ "expired": "Expired"
174
+ },
175
+ "revoke": "Revoke token",
176
+ "revoked": "Token revoked.",
177
+ "revokeError": "Could not revoke the token."
74
178
  }
75
179
  }
76
180
  }
@@ -39,4 +39,28 @@ export default defineMenuSource(() => {
39
39
  order: 20
40
40
  });
41
41
  }
42
+ if (config?.pages?.apiTokens) {
43
+ extendMenuItem("account", {
44
+ id: "api-tokens",
45
+ label: "API tokens",
46
+ labelKey: "account.menu.apiTokens.label",
47
+ description: "Create tokens for scripts and tools.",
48
+ descriptionKey: "account.menu.apiTokens.description",
49
+ icon: "i-lucide-key-round",
50
+ to: config.pages.apiTokens,
51
+ order: 25
52
+ });
53
+ }
54
+ if (config?.pages?.documents) {
55
+ extendMenuItem("account", {
56
+ id: "documents",
57
+ label: "Documents",
58
+ labelKey: "account.menu.documents.label",
59
+ description: "Handbooks and other files for you.",
60
+ descriptionKey: "account.menu.documents.description",
61
+ icon: "i-lucide-files",
62
+ to: config.pages.documents,
63
+ order: 30
64
+ });
65
+ }
42
66
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frigear-nu/account",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "A module for managing the account area (profile, email, password, security) in the main frigear app.",
5
5
  "homepage": "https://docs.frigear.dev/modules/account",
6
6
  "repository": {
@@ -24,31 +24,42 @@
24
24
  "playground"
25
25
  ],
26
26
  "dependencies": {
27
- "@frigear-nu/users": "1.0.8",
27
+ "@frigear-nu/module-kit": "1.0.0",
28
+ "@frigear-nu/auth": "0.0.4",
29
+ "@frigear-nu/users": "1.0.10",
28
30
  "@libsql/client": "^0.18.0",
29
31
  "@nuxt/kit": "^4.6.0",
32
+ "@vueuse/core": "^15.0.0",
30
33
  "drizzle-kit": "^0.31.11",
31
34
  "drizzle-orm": "^0.45.3",
32
- "zod": "^4.6.5",
33
- "@frigear-nu/menu": "0.0.8",
34
- "@frigear-nu/module-kit": "0.1.6",
35
- "@vueuse/core": "^15.0.0"
35
+ "zod": "^4.6.5"
36
36
  },
37
37
  "peerDependencies": {
38
- "@nuxthub/core": "^0.10.8",
39
- "@nuxt/ui": "^4.10.0"
38
+ "@frigear-nu/authorization": "0.0.7",
39
+ "@frigear-nu/menu": "0.0.10",
40
+ "@nuxt/ui": "^4.10.0",
41
+ "@nuxthub/core": "^0.10.8"
40
42
  },
41
43
  "peerDependenciesMeta": {
44
+ "@frigear-nu/authorization": {
45
+ "optional": true
46
+ },
47
+ "@frigear-nu/menu": {
48
+ "optional": true
49
+ },
42
50
  "@nuxt/ui": {
43
51
  "optional": true
44
52
  }
45
53
  },
46
54
  "devDependencies": {
55
+ "@frigear-nu/authorization": "0.0.7",
56
+ "@frigear-nu/menu": "0.0.10",
47
57
  "@nuxt/devtools": "^3.4.2",
48
58
  "@nuxt/eslint-config": "^1.17.0",
49
59
  "@nuxt/module-builder": "^1.0.3",
50
60
  "@nuxt/schema": "^4.6.0",
51
61
  "@nuxt/test-utils": "^4.3.2",
62
+ "@nuxt/ui": "^4.11.0",
52
63
  "@nuxthub/core": "^0.10.8",
53
64
  "@types/node": "latest",
54
65
  "changelogen": "^0.6.2",
@@ -56,8 +67,7 @@
56
67
  "nuxt": "^4.6.1",
57
68
  "typescript": "^6.0.3",
58
69
  "vitest": "^5.0.1",
59
- "vue-tsc": "^3.3.11",
60
- "@nuxt/ui": "^4.11.0"
70
+ "vue-tsc": "^3.3.11"
61
71
  },
62
72
  "scripts": {
63
73
  "postinstall": "nuxt-module-build build --stub && nuxt prepare",
@@ -1,24 +0,0 @@
1
- export declare const users: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
2
- name: "users";
3
- schema: undefined;
4
- columns: {
5
- acceptedTermsAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
6
- name: "accepted_terms_at";
7
- tableName: "users";
8
- dataType: "number";
9
- columnType: "SQLiteInteger";
10
- data: number;
11
- driverParam: number;
12
- notNull: false;
13
- hasDefault: false;
14
- isPrimaryKey: false;
15
- isAutoincrement: false;
16
- hasRuntimeDefault: false;
17
- enumValues: undefined;
18
- baseColumn: never;
19
- identity: undefined;
20
- generated: undefined;
21
- }, {}, {}>;
22
- };
23
- dialect: "sqlite";
24
- }>;
@@ -1,4 +0,0 @@
1
- import { sqliteTable, integer } from "drizzle-orm/sqlite-core";
2
- export const users = sqliteTable("users", {
3
- acceptedTermsAt: integer("accepted_terms_at")
4
- });
@@ -1,2 +0,0 @@
1
- declare const _default: any;
2
- export default _default;
@@ -1,20 +0,0 @@
1
- import { db, schema } from "@nuxthub/db";
2
- import { eq } from "drizzle-orm";
3
- import { z } from "zod";
4
- const bodySchema = z.object({
5
- email: z.string().email()
6
- });
7
- export default defineEventHandler(async (event) => {
8
- const { user } = await requireUserSession(event);
9
- const { email } = await readValidatedBody(event, bodySchema.parse);
10
- const existing = await db.query.users.findFirst({ where: (t, { eq: eq2 }) => eq2(t.email, email) });
11
- if (existing && existing.id !== user.id) {
12
- throw createError({ statusCode: 409, statusMessage: "A user with this email already exists." });
13
- }
14
- const [updated] = await db.update(schema.users).set({ email }).where(eq(schema.users.id, user.id)).returning();
15
- if (!updated) {
16
- throw createError({ statusCode: 404, statusMessage: "User not found." });
17
- }
18
- await setUserSession(event, { user: mapUserToSession(updated) });
19
- return { id: updated.id };
20
- });
@@ -1,2 +0,0 @@
1
- declare const _default: any;
2
- export default _default;
@@ -1,26 +0,0 @@
1
- import { db, schema } from "@nuxthub/db";
2
- import { eq } from "drizzle-orm";
3
- import { z } from "zod";
4
- const bodySchema = z.object({
5
- currentPassword: z.string().min(1),
6
- newPassword: z.string().min(8),
7
- confirmNewPassword: z.string().min(8)
8
- }).refine((data) => data.newPassword === data.confirmNewPassword, {
9
- message: "Passwords do not match.",
10
- path: ["confirmNewPassword"]
11
- });
12
- export default defineEventHandler(async (event) => {
13
- const { user } = await requireUserSession(event);
14
- const { currentPassword, newPassword } = await readValidatedBody(event, bodySchema.parse);
15
- const dbUser = await db.query.users.findFirst({ where: (t, { eq: eq2 }) => eq2(t.id, user.id) });
16
- if (!dbUser?.password || !await verifyPassword(dbUser.password, currentPassword)) {
17
- throw createError({ statusCode: 401, statusMessage: "Your current password is incorrect." });
18
- }
19
- const hashed = await hashPassword(newPassword);
20
- const [updated] = await db.update(schema.users).set({ password: hashed }).where(eq(schema.users.id, user.id)).returning();
21
- if (!updated) {
22
- throw createError({ statusCode: 404, statusMessage: "User not found." });
23
- }
24
- await setUserSession(event, { user: mapUserToSession(updated) });
25
- return { id: updated.id };
26
- });
@@ -1,2 +0,0 @@
1
- declare const _default: any;
2
- export default _default;
@@ -1,17 +0,0 @@
1
- import { db, schema } from "@nuxthub/db";
2
- import { eq } from "drizzle-orm";
3
- import { z } from "zod";
4
- const bodySchema = z.object({
5
- name: z.string().min(1),
6
- avatar: z.string().optional()
7
- });
8
- export default defineEventHandler(async (event) => {
9
- const { user } = await requireUserSession(event);
10
- const { name, avatar } = await readValidatedBody(event, bodySchema.parse);
11
- const [updated] = await db.update(schema.users).set({ name, avatar }).where(eq(schema.users.id, user.id)).returning();
12
- if (!updated) {
13
- throw createError({ statusCode: 404, statusMessage: "User not found." });
14
- }
15
- await setUserSession(event, { user: mapUserToSession(updated) });
16
- return { id: updated.id };
17
- });