@axium/client 0.34.0 → 0.35.0

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.
@@ -34,8 +34,8 @@ export declare const meta: Handle<z.ZodObject<{
34
34
  user: z.ZodObject<{
35
35
  id: z.ZodUUID;
36
36
  name: z.ZodString;
37
- username: z.ZodOptional<z.ZodNullable<z.ZodString>>;
38
- email: z.ZodEmail;
37
+ username: z.ZodString;
38
+ email: z.ZodOptional<z.ZodNullable<z.ZodEmail>>;
39
39
  emailVerified: z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>;
40
40
  preferences: z.ZodLazy<z.ZodObject<{
41
41
  debug: z.ZodDefault<z.ZodBoolean>;
@@ -10,7 +10,7 @@ export declare function session(): {
10
10
  user: {
11
11
  id: string;
12
12
  name: string;
13
- email: string;
13
+ username: string;
14
14
  preferences: {
15
15
  debug: boolean;
16
16
  };
@@ -19,7 +19,7 @@ export declare function session(): {
19
19
  registeredAt: Date;
20
20
  isAdmin: boolean;
21
21
  isSuspended: boolean;
22
- username?: string | null | undefined;
22
+ email?: string | null | undefined;
23
23
  emailVerified?: Date | null | undefined;
24
24
  };
25
25
  name?: string | null | undefined;
package/dist/locales.d.ts CHANGED
@@ -29,7 +29,6 @@ declare let currentLoaded: {
29
29
  readonly no_results: "No results";
30
30
  };
31
31
  readonly Login: {
32
- readonly email: "Email";
33
32
  readonly register: "Register instead";
34
33
  };
35
34
  readonly Logout: {
@@ -37,9 +36,7 @@ declare let currentLoaded: {
37
36
  readonly question: "Are you sure you want to log out?";
38
37
  };
39
38
  readonly Register: {
40
- readonly email: "Email";
41
39
  readonly login: "Login instead";
42
- readonly name: "Display Name";
43
40
  };
44
41
  readonly SessionList: {
45
42
  readonly created: "Created {date}";
@@ -84,6 +81,8 @@ declare let currentLoaded: {
84
81
  readonly none: "None";
85
82
  readonly ok: "Okay";
86
83
  readonly preferences: "Preferences";
84
+ readonly recovery: "Recovery";
85
+ readonly recovery_method_disabled: "This recovery method is disabled and can't be used.";
87
86
  readonly register: "Register";
88
87
  readonly rename: "Rename";
89
88
  readonly sessions: "Sessions";
@@ -91,7 +90,7 @@ declare let currentLoaded: {
91
90
  readonly success: "Success";
92
91
  readonly unknown: "Unknown";
93
92
  readonly unnamed: "Unnamed";
94
- readonly user_display_name: "Name";
93
+ readonly user_display_name: "Display name";
95
94
  readonly username: "Username";
96
95
  readonly yes: "Yes";
97
96
  };
@@ -127,6 +126,8 @@ declare let currentLoaded: {
127
126
  readonly toast_updated: "Profile picture updated";
128
127
  };
129
128
  readonly preferences: "Preferences";
129
+ readonly remove_email: "Remove email";
130
+ readonly remove_email_confirm: "Are you sure you want to remove your recovery email?";
130
131
  readonly sessions: "Sessions";
131
132
  readonly title: "Your Account";
132
133
  readonly toast_username_updated: "Username updated";
package/dist/user.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { NewSessionResponse, Passkey, PasskeyChangeable, Session, User, UserChangeable, UserPublic, Verification } from '@axium/core';
1
+ import type { AuthInfo, NewSessionResponse, Passkey, PasskeyChangeable, Session, User, UserChangeable, UserPublic, Verification } from '@axium/core';
2
2
  import * as z from 'zod';
3
3
  import Cache from './cache.js';
4
4
  export declare function login(userId: string): Promise<NewSessionResponse>;
@@ -6,7 +6,7 @@ export declare function login(userId: string): Promise<NewSessionResponse>;
6
6
  * Create an elevated session for the user to perform sensitive actions.
7
7
  */
8
8
  export declare function elevate(userId: string): Promise<void>;
9
- export declare function loginByEmail(email: string): Promise<NewSessionResponse>;
9
+ export declare function loginByUsername(username: string): Promise<NewSessionResponse>;
10
10
  export declare function getCurrentSession(): Promise<Session & {
11
11
  user: User;
12
12
  }>;
@@ -27,7 +27,10 @@ export declare function fullUserInfo(userId: string): Promise<User & {
27
27
  * @param deletingId The UUID of the user performing the deletion (for authentication). Defaults to userId.
28
28
  */
29
29
  export declare function deleteUser(userId: string, deletingId?: string): Promise<User>;
30
- export declare function emailVerificationEnabled(userId: string): Promise<boolean>;
30
+ /**
31
+ * Get which authentication-related features are available, e.g. account recovery methods.
32
+ */
33
+ export declare function getAuthInfo(userId: string): Promise<AuthInfo>;
31
34
  export declare function sendVerificationEmail(userId: string): Promise<Verification>;
32
35
  export declare function verifyEmail(userId: string, token: string): Promise<void>;
33
36
  export declare function getPasskeys(userId: string): Promise<Passkey[]>;
package/dist/user.js CHANGED
@@ -1,7 +1,8 @@
1
+ import { UserRegistrationInit } from '@axium/core/user';
1
2
  import { startAuthentication, startRegistration } from '@simplewebauthn/browser';
2
3
  import * as z from 'zod';
3
- import { fetchAPI } from './requests.js';
4
4
  import Cache from './cache.js';
5
+ import { fetchAPI } from './requests.js';
5
6
  export async function login(userId) {
6
7
  const options = await fetchAPI('PUT', 'users/:id/auth', { type: 'login' }, userId);
7
8
  const response = await startAuthentication({ optionsJSON: options });
@@ -15,11 +16,8 @@ export async function elevate(userId) {
15
16
  const response = await startAuthentication({ optionsJSON: options });
16
17
  await fetchAPI('POST', 'users/:id/auth', response, userId);
17
18
  }
18
- export async function loginByEmail(email) {
19
- const { id: userId } = await fetchAPI('POST', 'user_id', {
20
- using: 'email',
21
- value: email,
22
- });
19
+ export async function loginByUsername(username) {
20
+ const { id: userId } = await fetchAPI('POST', 'user_id', { using: 'username', value: username });
23
21
  return await login(userId);
24
22
  }
25
23
  let _currentSession = null;
@@ -44,15 +42,10 @@ export async function logoutCurrentSession() {
44
42
  return await fetchAPI('DELETE', 'session');
45
43
  }
46
44
  export async function register(_data) {
47
- const data = z.object({ name: z.string(), email: z.email() }).parse(_data);
45
+ const data = UserRegistrationInit.parse(_data);
48
46
  const { options, userId } = await fetchAPI('PUT', 'register', data);
49
47
  const response = await startRegistration({ optionsJSON: options });
50
- await fetchAPI('POST', 'register', {
51
- userId,
52
- name: data.name,
53
- email: data.email,
54
- response,
55
- });
48
+ await fetchAPI('POST', 'register', { userId, response, ...data });
56
49
  }
57
50
  function _checkId(userId) {
58
51
  try {
@@ -91,10 +84,12 @@ export async function deleteUser(userId, deletingId = userId) {
91
84
  userCache.invalidate(userId);
92
85
  return result;
93
86
  }
94
- export async function emailVerificationEnabled(userId) {
87
+ /**
88
+ * Get which authentication-related features are available, e.g. account recovery methods.
89
+ */
90
+ export async function getAuthInfo(userId) {
95
91
  _checkId(userId);
96
- const { enabled } = await fetchAPI('OPTIONS', 'users/:id/verify/email', {}, userId);
97
- return enabled;
92
+ return await fetchAPI('OPTIONS', 'users/:id/auth', {}, userId);
98
93
  }
99
94
  export async function sendVerificationEmail(userId) {
100
95
  _checkId(userId);
@@ -16,7 +16,7 @@
16
16
  /** The committed value being edited. */
17
17
  value?: string | null;
18
18
  /** Called with the new value when a change is confirmed. `null` means the value was cleared (only possible when `optional`). */
19
- commit(value: string | null): unknown;
19
+ commit(value: string): unknown;
20
20
  /** Called when editing ends, whether or not a change was committed. */
21
21
  close(): void;
22
22
  /** Validates the draft as the user types and before committing. Errors float above the input. */
@@ -42,7 +42,7 @@
42
42
  const newValue = draft.trim() || null;
43
43
  if (newValue === (value ?? null) || (newValue === null && !optional)) return close();
44
44
  if (!validate(newValue)) return;
45
- commit(newValue);
45
+ commit(newValue!);
46
46
  close();
47
47
  }
48
48
  </script>
package/lib/Login.svelte CHANGED
@@ -1,16 +1,16 @@
1
1
  <script lang="ts">
2
- import { loginByEmail, text } from '@axium/client';
2
+ import { loginByUsername, text } from '@axium/client';
3
3
  import FormDialog from './FormDialog.svelte';
4
4
  import authRedirect from './auth_redirect.js';
5
5
 
6
6
  let { dialog = $bindable(), fullPage = false }: { dialog?: HTMLDialogElement; fullPage?: boolean } = $props();
7
7
 
8
- async function submit(data: { email: string }) {
9
- if (typeof data.email != 'string') {
10
- throw 'Tried to upload a file for an email. Huh?!';
8
+ async function submit(data: { username: string }) {
9
+ if (typeof data.username != 'string') {
10
+ throw 'Tried to upload a file for a username. Huh?!';
11
11
  }
12
12
 
13
- await loginByEmail(data.email);
13
+ await loginByUsername(data.username);
14
14
  const redirectAfter = await authRedirect();
15
15
  if (fullPage && redirectAfter) location.href = redirectAfter;
16
16
  }
@@ -18,8 +18,8 @@
18
18
 
19
19
  <FormDialog bind:dialog submitText={text('generic.login')} {submit} pageMode={fullPage}>
20
20
  <div>
21
- <label for="email">{text('Login.email')}</label>
22
- <input name="email" type="email" required />
21
+ <label for="username">{text('generic.username')}</label>
22
+ <input name="username" type="text" required />
23
23
  </div>
24
24
  {#snippet footer()}
25
25
  {#if fullPage}
@@ -14,12 +14,12 @@
14
14
 
15
15
  <FormDialog bind:dialog submitText={text('generic.register')} {submit} pageMode={fullPage}>
16
16
  <div>
17
- <label for="name">{text('Register.name')}</label>
17
+ <label for="name">{text('generic.user_display_name')}</label>
18
18
  <input name="name" type="text" required />
19
19
  </div>
20
20
  <div>
21
- <label for="email">{text('Register.email')}</label>
22
- <input name="email" type="email" required />
21
+ <label for="username">{text('generic.username')}</label>
22
+ <input name="username" type="text" required />
23
23
  </div>
24
24
  {#snippet footer()}
25
25
  {#if fullPage}
package/locales/en.json CHANGED
@@ -23,7 +23,6 @@
23
23
  "no_results": "No results"
24
24
  },
25
25
  "Login": {
26
- "email": "Email",
27
26
  "register": "Register instead"
28
27
  },
29
28
  "Logout": {
@@ -31,9 +30,7 @@
31
30
  "question": "Are you sure you want to log out?"
32
31
  },
33
32
  "Register": {
34
- "email": "Email",
35
- "login": "Login instead",
36
- "name": "Display Name"
33
+ "login": "Login instead"
37
34
  },
38
35
  "SessionList": {
39
36
  "created": "Created {date}",
@@ -78,6 +75,8 @@
78
75
  "none": "None",
79
76
  "ok": "Okay",
80
77
  "preferences": "Preferences",
78
+ "recovery": "Recovery",
79
+ "recovery_method_disabled": "This recovery method is disabled and can't be used.",
81
80
  "register": "Register",
82
81
  "rename": "Rename",
83
82
  "sessions": "Sessions",
@@ -85,7 +84,7 @@
85
84
  "success": "Success",
86
85
  "unknown": "Unknown",
87
86
  "unnamed": "Unnamed",
88
- "user_display_name": "Name",
87
+ "user_display_name": "Display name",
89
88
  "username": "Username",
90
89
  "yes": "Yes"
91
90
  },
@@ -121,6 +120,8 @@
121
120
  "toast_updated": "Profile picture updated"
122
121
  },
123
122
  "preferences": "Preferences",
123
+ "remove_email": "Remove email",
124
+ "remove_email_confirm": "Are you sure you want to remove your recovery email?",
124
125
  "sessions": "Sessions",
125
126
  "title": "Your Account",
126
127
  "toast_username_updated": "Username updated",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axium/client",
3
- "version": "0.34.0",
3
+ "version": "0.35.0",
4
4
  "author": "James Prevett <jp@jamespre.dev>",
5
5
  "funding": {
6
6
  "type": "individual",
@@ -49,7 +49,7 @@
49
49
  "build": "tsc"
50
50
  },
51
51
  "peerDependencies": {
52
- "@axium/core": ">=0.36.1",
52
+ "@axium/core": ">=0.37.0",
53
53
  "ioium": "^1.7.0",
54
54
  "semver": "^7.7.4",
55
55
  "svelte": "^5.36.0",