@webx-ui/module-auth 0.13.0 → 0.14.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.
package/dist/index.d.ts CHANGED
@@ -37,10 +37,35 @@ export { default as WxAdminsPage } from './AdminsPage';
37
37
  export { default as WxAdminList } from './AdminList';
38
38
  export { default as WxAgentCallList } from './CallList';
39
39
  export { default as WxConnectionList } from './ConnectionList';
40
- export declare const WxConnectPage: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
40
+ export declare const WxConnectPage: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
41
+ 'own-keys': import('vue').CreateComponentPublicInstanceWithMixins<Readonly<{
42
+ mine?: boolean;
43
+ }> & Readonly<{}>, {
44
+ reload: () => Promise<void>;
45
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, import('vue').PublicProps, {
46
+ mine: boolean;
47
+ }, false, {}, {}, import('vue').GlobalComponents, import('vue').GlobalDirectives, string, {
48
+ root: HTMLDivElement;
49
+ }, HTMLDivElement, import('vue').ComponentProvideOptions, {
50
+ P: {};
51
+ B: {};
52
+ D: {};
53
+ C: {};
54
+ M: {};
55
+ Defaults: {};
56
+ }, Readonly<{
57
+ mine?: boolean;
58
+ }> & Readonly<{}>, {
59
+ reload: () => Promise<void>;
60
+ }, {}, {}, {}, {
61
+ mine: boolean;
62
+ }> | null;
63
+ }, HTMLDivElement>;
41
64
  export { default as WxKeyList } from './KeyList';
42
- export type { Admin, AdminInput, AdminPage, AdminQuery, AdminRole, AgentCall, AgentCallFilters, AgentCallOutcome, AgentCallPage, AgentCallQuery, Connection, ConnectionScope, Connections, IssuedMcpKey, McpKey, McpKeyInput, McpKeys, Role, } from './types';
43
- export { createAuthSession, provideAuth, useAuth, authKey, avatarFieldKey, avatarResolverKey, type ProfileInput, } from './session';
65
+ export { default as WxRoleList } from './RoleList';
66
+ export { default as WxRoleDialog } from './RoleDialog';
67
+ export type { Admin, AdminInput, AdminPage, AdminQuery, AdminRole, AgentCall, AgentCallFilters, AgentCallOutcome, AgentCallPage, AgentCallQuery, Connection, ConnectionScope, Connections, IssuedMcpKey, McpKey, McpKeyInput, McpKeys, PermissionCell, PermissionRow, Role, RoleDetails, RoleInput, } from './types';
68
+ export { createAuthSession, provideAuth, useAuth, authKey, avatarFieldKey, avatarResolverKey, type EmailChangeSent, type ProfileInput, } from './session';
44
69
  export { default as WxProfileDialog } from './ProfileDialog';
45
70
  export type { AuthSession, AvatarResolver, Credentials } from './session';
46
71
  export { default as WxLoginCard } from './LoginCard';
package/dist/index.js CHANGED
@@ -1,29 +1,32 @@
1
1
  import "vue";
2
- import { b as t, d as i, e as n, W as o, a as r, f as A, L as c, P as d, U as x, g as W, h as l, i as m, j as u, k as g, l as h, m as p, n as L, o as v, p as y, q as C, r as K, s as P, t as f, v as M } from "./index-BUVSIwLQ.js";
2
+ import "@webx-ui/core";
3
+ import { e as i, f as n, g as o, W as r, b as x, c, L as l, P as A, h as W, i as m, U as d, j as g, k as p, l as u, m as h, n as L, o as y, p as v, q as C, r as K, s as P, t as f, v as R, w as D, x as M, y as U } from "./index-Bd6Dkuu8.js";
3
4
  export {
4
- t as WxAdminList,
5
- i as WxAdminsPage,
6
- n as WxAgentCallList,
7
- o as WxConnectPage,
8
- r as WxConnectionList,
9
- A as WxKeyList,
10
- c as WxLoginCard,
11
- d as WxProfileDialog,
12
- x as WxUserMenu,
13
- W as admins,
14
- l as auth,
15
- m as authKey,
16
- u as authMessages,
17
- g as avatarFieldKey,
18
- h as avatarResolverKey,
19
- p as connect,
20
- L as createAdminsApi,
21
- v as createAuthSession,
22
- y as createConnectionsApi,
23
- C as createKeysApi,
24
- K as provideAuth,
25
- P as selectAdmin,
26
- f as selectAdmins,
27
- M as useAuth
5
+ i as WxAdminList,
6
+ n as WxAdminsPage,
7
+ o as WxAgentCallList,
8
+ r as WxConnectPage,
9
+ x as WxConnectionList,
10
+ c as WxKeyList,
11
+ l as WxLoginCard,
12
+ A as WxProfileDialog,
13
+ W as WxRoleDialog,
14
+ m as WxRoleList,
15
+ d as WxUserMenu,
16
+ g as admins,
17
+ p as auth,
18
+ u as authKey,
19
+ h as authMessages,
20
+ L as avatarFieldKey,
21
+ y as avatarResolverKey,
22
+ v as connect,
23
+ C as createAdminsApi,
24
+ K as createAuthSession,
25
+ P as createConnectionsApi,
26
+ f as createKeysApi,
27
+ R as provideAuth,
28
+ D as selectAdmin,
29
+ M as selectAdmins,
30
+ U as useAuth
28
31
  };
29
32
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
package/dist/keys.d.ts CHANGED
@@ -1,8 +1,18 @@
1
1
  import { AdminContext } from '@webx-ui/module-admin';
2
2
  import { IssuedMcpKey, McpKey, McpKeyInput, McpKeys } from './types';
3
3
  export interface KeysApi {
4
- /** Every key, live ones first. Behind `admins.manage`. */
5
- list(): Promise<McpKeys>;
4
+ /**
5
+ * Live ones first: your own, or everybody's with `admins.manage` — unless `mine` asks for
6
+ * your own even then.
7
+ */
8
+ list(options?: {
9
+ mine?: boolean;
10
+ }): Promise<McpKeys>;
11
+ /**
12
+ * The scopes a key for this administrator may carry — those their permissions reach, and
13
+ * `mcp:use`. Yourself when nobody is named; somebody else needs `admins.manage`.
14
+ */
15
+ scopesFor(admin?: number): Promise<string[]>;
6
16
  /** Issue one. The answer carries the secret, once. */
7
17
  issue(input: McpKeyInput): Promise<IssuedMcpKey>;
8
18
  /** Switch one off. The row stays; the key stops working at once. */
package/dist/module.d.ts CHANGED
@@ -13,8 +13,8 @@ export interface AdminsOptions {
13
13
  /** Turns an avatar key into an address. Omitted, rows and forms show initials. */
14
14
  resolveAvatar?: (key: string) => Promise<string | null>;
15
15
  }
16
- /** Which of the four views of the administrators section a route opens. */
17
- export type AdminsView = 'admins' | 'calls' | 'connections' | 'keys';
16
+ /** Which of the five views of the administrators section a route opens. */
17
+ export type AdminsView = 'admins' | 'roles' | 'calls' | 'connections' | 'keys';
18
18
  /**
19
19
  * The administrators, as a section of the panel.
20
20
  *
package/dist/session.d.ts CHANGED
@@ -40,6 +40,17 @@ export interface AuthSession {
40
40
  * a password to rotate.
41
41
  */
42
42
  updateProfile(profile: ProfileInput): Promise<AdminUser>;
43
+ /**
44
+ * Ask for a new sign-in address. Changes nothing: a letter goes to the new address, and the
45
+ * link in it makes the move. Throws `HttpError` with a 422 under `email` where the site sends
46
+ * no mail, the address is taken, or the password is wrong (under `current_password`).
47
+ */
48
+ requestEmailChange(email: string, currentPassword: string): Promise<EmailChangeSent>;
49
+ }
50
+ /** Where the letter went, and how long its link works. */
51
+ export interface EmailChangeSent {
52
+ email: string;
53
+ minutes: number;
43
54
  }
44
55
  /** What somebody may send about themselves. A blank password is "leave it alone". */
45
56
  export interface ProfileInput {
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .wx-login[data-v-3c206e31]{width:100%;max-width:26rem}.wx-login__message[data-v-3c206e31]{margin-block-end:var(--wx-space-4)}.wx-login__remember[data-v-3c206e31]{margin-block-start:calc(-1 * var(--wx-space-12))}.wx-login__reveal[data-v-3c206e31]{display:inline-flex;align-items:center;padding:0;font:inherit;color:var(--wx-text-muted);background:none;border:0;cursor:pointer}.wx-login__reveal[data-v-3c206e31]:hover,.wx-login__reveal[aria-pressed=true][data-v-3c206e31]{color:var(--wx-text-default)}.wx-admin-form{container-type:inline-size}.wx-admin-form__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--wx-space-24)}.wx-admin-form__grid.has-aside{grid-template-columns:200px minmax(0,1fr)}.wx-admin-form__fields{display:flex;flex-direction:column;gap:var(--wx-space-12);min-width:0}@container (max-width: 520px){.wx-admin-form__grid.has-aside{grid-template-columns:minmax(0,1fr)}.wx-admin-form__aside{max-width:200px}}.wx-admin-list,.wx-call-list{min-width:0}.wx-call-list__details{display:flex;flex-direction:column;gap:var(--wx-space-8);padding:var(--wx-space-8) var(--wx-space-16)}.wx-call-list__card-details{margin-top:var(--wx-space-8)}.wx-call-list__glyph{display:flex;align-items:center;justify-content:center;width:100%;height:100%;color:var(--wx-text-muted);background:var(--wx-bg-subtle)}.wx-call-list__label{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--wx-space-4) var(--wx-space-8)}.wx-call-list__arguments{margin:0;padding:var(--wx-space-8) var(--wx-space-12);max-height:320px;overflow:auto;border:1px solid var(--wx-border-muted);border-radius:var(--wx-radius-sm);background:var(--wx-bg-surface);color:var(--wx-text-default);font-family:var(--wx-font-family-mono);font-size:var(--wx-font-size-xs);line-height:var(--wx-font-line-height-relaxed);white-space:pre-wrap;word-break:break-word}.wx-connection-list{min-width:0}.wx-connection-list__glyph{display:flex;align-items:center;justify-content:center;width:100%;height:100%;color:var(--wx-text-muted);background:var(--wx-bg-subtle)}.wx-connection-list .wx-table__row.is-ended,.wx-connection-list .wx-table__card.is-ended{opacity:.6}.wx-key-dialog{display:flex;flex-direction:column;gap:var(--wx-space-12);min-width:0;container-type:inline-size}.wx-key-dialog__secret{display:flex;gap:var(--wx-space-8);min-width:0}.wx-key-dialog__secret>:first-child{flex:1 1 auto;min-width:0}@container (max-width: 420px){.wx-key-dialog__secret{flex-direction:column}}.wx-key-list{min-width:0}.wx-key-list__glyph{display:flex;align-items:center;justify-content:center;width:100%;height:100%;color:var(--wx-text-muted);background:var(--wx-bg-subtle)}.wx-key-list .wx-table__row.is-ended,.wx-key-list .wx-table__card.is-ended{opacity:.6}.wx-profile-host[data-v-9583a67a]{container-type:inline-size}.wx-profile[data-v-9583a67a]{display:flex;gap:var(--wx-space-16)}.wx-profile__aside[data-v-9583a67a]{flex:0 0 180px}.wx-profile__fields[data-v-9583a67a]{display:flex;flex-direction:column;gap:var(--wx-space-12);flex:1 1 auto;min-width:0}@container (max-width: 480px){.wx-profile[data-v-9583a67a]{flex-direction:column}.wx-profile__aside[data-v-9583a67a]{flex:none}}.wx-user-menu__theme[data-v-31b12be6]{padding:var(--wx-space-2) var(--wx-space-8) var(--wx-space-6)}.wx-user-menu__trigger[data-v-31b12be6]{display:inline-flex;padding:0;border:none;border-radius:var(--wx-radius-full);background:transparent;cursor:pointer;transition:opacity var(--wx-duration-fast) var(--wx-easing-standard)}.wx-user-menu__trigger[data-v-31b12be6]:hover{opacity:.85}.wx-user-menu__trigger[data-v-31b12be6]:focus-visible{outline:2px solid var(--wx-border-focus);outline-offset:2px}.wx-user-menu__trigger--named[data-v-31b12be6]{align-items:center;gap:var(--wx-space-8);width:100%;min-width:0;padding:var(--wx-space-4);border-radius:var(--wx-radius-control);text-align:start}.wx-user-menu__trigger--named[data-v-31b12be6]:hover{opacity:1;background:var(--wx-bg-subtle)}.wx-user-menu__who[data-v-31b12be6]{display:flex;flex:1 1 auto;flex-direction:column;min-width:0;font-family:var(--wx-font-family-sans);line-height:1.3}.wx-user-menu__name[data-v-31b12be6],.wx-user-menu__email[data-v-31b12be6]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wx-user-menu__name[data-v-31b12be6]{color:var(--wx-text-default);font-size:var(--wx-font-size-sm);font-weight:var(--wx-font-weight-medium)}.wx-user-menu__email[data-v-31b12be6]{color:var(--wx-text-muted);font-size:var(--wx-font-size-xs)}.wx-user-menu__chevron[data-v-31b12be6]{flex:none;color:var(--wx-text-muted)}.wx-content-rules[data-v-55be157e]{display:flex;flex-direction:column;gap:var(--wx-space-12);min-width:0}.wx-content-rules__foot[data-v-55be157e]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--wx-space-12)}.wx-connect[data-v-19a489e0]{display:flex;flex-direction:column;gap:var(--wx-space-24);min-width:0}.wx-connect__lead[data-v-19a489e0]{max-width:68ch}.wx-connect__row[data-v-19a489e0]{display:flex;flex-wrap:wrap;align-items:center;gap:var(--wx-space-12)}.wx-connect__url[data-v-19a489e0]{flex:1 1 260px;min-width:0;padding:var(--wx-space-10) var(--wx-space-12);border-radius:var(--wx-radius-sm);background:var(--wx-bg-subtle);color:var(--wx-text-default);font-family:var(--wx-font-family-mono);font-size:var(--wx-font-size-md);word-break:break-all}.wx-connect__section[data-v-19a489e0]{display:flex;flex-direction:column;gap:var(--wx-space-12);min-width:0}.wx-connect__steps[data-v-19a489e0]{display:flex;flex-direction:column;gap:var(--wx-space-8);margin:0;padding-left:var(--wx-space-24);color:var(--wx-text-default);font-size:var(--wx-font-size-sm);line-height:var(--wx-font-line-height-relaxed)}.wx-connect__snippet[data-v-19a489e0]{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:var(--wx-space-8);padding:var(--wx-space-12);border-radius:var(--wx-radius-sm);background:var(--wx-bg-subtle)}.wx-connect__snippet pre[data-v-19a489e0]{flex:1 1 240px;margin:0;min-width:0;color:var(--wx-text-default);font-family:var(--wx-font-family-mono);font-size:var(--wx-font-size-xs);line-height:var(--wx-font-line-height-relaxed);white-space:pre-wrap;word-break:break-all}.wx-connect__links[data-v-19a489e0]{display:flex;flex-wrap:wrap;gap:var(--wx-space-12)}
1
+ .wx-login[data-v-3c206e31]{width:100%;max-width:26rem}.wx-login__message[data-v-3c206e31]{margin-block-end:var(--wx-space-4)}.wx-login__remember[data-v-3c206e31]{margin-block-start:calc(-1 * var(--wx-space-12))}.wx-login__reveal[data-v-3c206e31]{display:inline-flex;align-items:center;padding:0;font:inherit;color:var(--wx-text-muted);background:none;border:0;cursor:pointer}.wx-login__reveal[data-v-3c206e31]:hover,.wx-login__reveal[aria-pressed=true][data-v-3c206e31]{color:var(--wx-text-default)}.wx-admin-form{container-type:inline-size}.wx-admin-form__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--wx-space-24)}.wx-admin-form__grid.has-aside{grid-template-columns:200px minmax(0,1fr)}.wx-admin-form__fields{display:flex;flex-direction:column;gap:var(--wx-space-12);min-width:0}@container (max-width: 520px){.wx-admin-form__grid.has-aside{grid-template-columns:minmax(0,1fr)}.wx-admin-form__aside{max-width:200px}}.wx-admin-list,.wx-call-list{min-width:0}.wx-call-list__details{display:flex;flex-direction:column;gap:var(--wx-space-8);padding:var(--wx-space-8) var(--wx-space-16)}.wx-call-list__card-details{margin-top:var(--wx-space-8)}.wx-call-list__glyph{display:flex;align-items:center;justify-content:center;width:100%;height:100%;color:var(--wx-text-muted);background:var(--wx-bg-subtle)}.wx-call-list__label{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--wx-space-4) var(--wx-space-8)}.wx-call-list__arguments{margin:0;padding:var(--wx-space-8) var(--wx-space-12);max-height:320px;overflow:auto;border:1px solid var(--wx-border-muted);border-radius:var(--wx-radius-sm);background:var(--wx-bg-surface);color:var(--wx-text-default);font-family:var(--wx-font-family-mono);font-size:var(--wx-font-size-xs);line-height:var(--wx-font-line-height-relaxed);white-space:pre-wrap;word-break:break-word}.wx-connection-list{min-width:0}.wx-connection-list__glyph{display:flex;align-items:center;justify-content:center;width:100%;height:100%;color:var(--wx-text-muted);background:var(--wx-bg-subtle)}.wx-connection-list .wx-table__row.is-ended,.wx-connection-list .wx-table__card.is-ended{opacity:.6}.wx-key-dialog{display:flex;flex-direction:column;gap:var(--wx-space-12);min-width:0;container-type:inline-size}.wx-key-dialog__secret{display:flex;gap:var(--wx-space-8);min-width:0}.wx-key-dialog__secret>:first-child{flex:1 1 auto;min-width:0}@container (max-width: 420px){.wx-key-dialog__secret{flex-direction:column}}.wx-key-list{min-width:0}.wx-key-list__glyph{display:flex;align-items:center;justify-content:center;width:100%;height:100%;color:var(--wx-text-muted);background:var(--wx-bg-subtle)}.wx-key-list .wx-table__row.is-ended,.wx-key-list .wx-table__card.is-ended{opacity:.6}.wx-role-form{container-type:inline-size;display:flex;flex-direction:column;gap:var(--wx-space-12);min-width:0}.wx-role-form__names{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--wx-space-12)}.wx-role-form__matrix{display:flex;flex-direction:column;border:1px solid var(--wx-border-default);border-radius:var(--wx-radius-md)}.wx-role-form__row{display:grid;grid-template-columns:minmax(0,200px) minmax(0,1fr);gap:var(--wx-space-12);padding:var(--wx-space-12) var(--wx-space-16)}.wx-role-form__row+.wx-role-form__row{border-top:1px solid var(--wx-border-muted)}.wx-role-form__cells{display:flex;flex-wrap:wrap;gap:var(--wx-space-8) var(--wx-space-24);min-width:0}.wx-role-form__label{display:inline-flex;flex-direction:column;min-width:0}.wx-role-form__code{font-family:var(--wx-font-family-mono);font-size:var(--wx-font-size-xs);color:var(--wx-text-muted);overflow-wrap:anywhere}@container (max-width: 560px){.wx-role-form__names,.wx-role-form__row{grid-template-columns:minmax(0,1fr)}.wx-role-form__row{gap:var(--wx-space-8);padding:var(--wx-space-12)}}.wx-role-list{min-width:0}.wx-role-list__name{display:inline-flex;align-items:center;gap:var(--wx-space-8);flex-wrap:wrap}.wx-role-list__slug{font-family:var(--wx-font-family-mono)}.wx-profile-host[data-v-39b6c2a5]{container-type:inline-size}.wx-profile[data-v-39b6c2a5]{display:flex;gap:var(--wx-space-16);padding-top:var(--wx-space-16)}.wx-profile__aside[data-v-39b6c2a5]{flex:0 0 180px}.wx-profile__fields[data-v-39b6c2a5],.wx-profile__section[data-v-39b6c2a5]{display:flex;flex-direction:column;gap:var(--wx-space-12);flex:1 1 auto;min-width:0}.wx-profile__section[data-v-39b6c2a5]{padding-top:var(--wx-space-16)}.wx-profile__agents[data-v-39b6c2a5]{display:flex;align-items:center;justify-content:space-between;gap:var(--wx-space-12);padding:var(--wx-space-12);border:1px solid var(--wx-border-default);border-radius:var(--wx-radius-sm)}.wx-profile__agents-text[data-v-39b6c2a5]{display:flex;flex-direction:column;gap:var(--wx-space-2);min-width:0}@container (max-width: 480px){.wx-profile[data-v-39b6c2a5]{flex-direction:column}.wx-profile__aside[data-v-39b6c2a5]{flex:none}}.wx-user-menu__theme[data-v-31b12be6]{padding:var(--wx-space-2) var(--wx-space-8) var(--wx-space-6)}.wx-user-menu__trigger[data-v-31b12be6]{display:inline-flex;padding:0;border:none;border-radius:var(--wx-radius-full);background:transparent;cursor:pointer;transition:opacity var(--wx-duration-fast) var(--wx-easing-standard)}.wx-user-menu__trigger[data-v-31b12be6]:hover{opacity:.85}.wx-user-menu__trigger[data-v-31b12be6]:focus-visible{outline:2px solid var(--wx-border-focus);outline-offset:2px}.wx-user-menu__trigger--named[data-v-31b12be6]{align-items:center;gap:var(--wx-space-8);width:100%;min-width:0;padding:var(--wx-space-4);border-radius:var(--wx-radius-control);text-align:start}.wx-user-menu__trigger--named[data-v-31b12be6]:hover{opacity:1;background:var(--wx-bg-subtle)}.wx-user-menu__who[data-v-31b12be6]{display:flex;flex:1 1 auto;flex-direction:column;min-width:0;font-family:var(--wx-font-family-sans);line-height:1.3}.wx-user-menu__name[data-v-31b12be6],.wx-user-menu__email[data-v-31b12be6]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wx-user-menu__name[data-v-31b12be6]{color:var(--wx-text-default);font-size:var(--wx-font-size-sm);font-weight:var(--wx-font-weight-medium)}.wx-user-menu__email[data-v-31b12be6]{color:var(--wx-text-muted);font-size:var(--wx-font-size-xs)}.wx-user-menu__chevron[data-v-31b12be6]{flex:none;color:var(--wx-text-muted)}.wx-content-rules[data-v-55be157e]{display:flex;flex-direction:column;gap:var(--wx-space-12);min-width:0}.wx-content-rules__foot[data-v-55be157e]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--wx-space-12)}.wx-connect[data-v-73da42dd]{display:flex;flex-direction:column;gap:var(--wx-space-24);min-width:0}.wx-connect__lead[data-v-73da42dd]{max-width:68ch}.wx-connect__row[data-v-73da42dd]{display:flex;flex-wrap:wrap;align-items:center;gap:var(--wx-space-12)}.wx-connect__url[data-v-73da42dd]{flex:1 1 260px;min-width:0;padding:var(--wx-space-10) var(--wx-space-12);border-radius:var(--wx-radius-sm);background:var(--wx-bg-subtle);color:var(--wx-text-default);font-family:var(--wx-font-family-mono);font-size:var(--wx-font-size-md);word-break:break-all}.wx-connect__section[data-v-73da42dd]{display:flex;flex-direction:column;gap:var(--wx-space-12);min-width:0}.wx-connect__steps[data-v-73da42dd]{display:flex;flex-direction:column;gap:var(--wx-space-8);margin:0;padding-left:var(--wx-space-24);color:var(--wx-text-default);font-size:var(--wx-font-size-sm);line-height:var(--wx-font-line-height-relaxed)}.wx-connect__snippet[data-v-73da42dd]{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:var(--wx-space-8);padding:var(--wx-space-12);border-radius:var(--wx-radius-sm);background:var(--wx-bg-subtle)}.wx-connect__snippet pre[data-v-73da42dd]{flex:1 1 240px;margin:0;min-width:0;color:var(--wx-text-default);font-family:var(--wx-font-family-mono);font-size:var(--wx-font-size-xs);line-height:var(--wx-font-line-height-relaxed);white-space:pre-wrap;word-break:break-all}.wx-connect__head[data-v-73da42dd]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--wx-space-8)}.wx-connect__links[data-v-73da42dd]{display:flex;flex-wrap:wrap;gap:var(--wx-space-12)}
package/dist/types.d.ts CHANGED
@@ -8,6 +8,41 @@ export interface Role extends AdminRole {
8
8
  permissions: string[];
9
9
  /** How many administrators hold it — the number that makes a role safe or risky to change. */
10
10
  users: number;
11
+ /**
12
+ * Whether the reader holds it. Such a role is somebody else's to edit (rule 5 of
13
+ * WEBX_UI_PERMISSIONS.md §6.2), so the form opens it read-only. Absent from an older server.
14
+ */
15
+ held?: boolean;
16
+ /** A table row, for `WxTable`; see `Admin`. */
17
+ [key: string]: unknown;
18
+ }
19
+ /** One role and the people it would be taken from, for the question before deleting it. */
20
+ export interface RoleDetails extends Role {
21
+ holders: {
22
+ id: number;
23
+ name: string;
24
+ email: string;
25
+ }[];
26
+ }
27
+ /** What the role form sends. A code left out is made from the name. */
28
+ export interface RoleInput {
29
+ name: string;
30
+ slug?: string | null;
31
+ permissions: string[];
32
+ }
33
+ /** A permission as the matrix of the role form shows it. */
34
+ export interface PermissionCell {
35
+ name: string;
36
+ /** In the panel's language, from the server. */
37
+ label: string;
38
+ /** Whether the reader holds it — what they do not hold, they cannot grant (rule 2). */
39
+ held: boolean;
40
+ }
41
+ /** One module's row of the matrix, in the order of the menu. */
42
+ export interface PermissionRow {
43
+ module: string;
44
+ title: string;
45
+ permissions: PermissionCell[];
11
46
  }
12
47
  export interface Admin {
13
48
  id: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webx-ui/module-auth",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Signing in to a WebX UI admin panel: the screen, the session and the router guard. Pairs with webx-ui/module-auth on the server.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -44,7 +44,7 @@
44
44
  "vue-router": "^4.5.0"
45
45
  },
46
46
  "dependencies": {
47
- "@webx-ui/module-admin": "^0.30.0",
47
+ "@webx-ui/module-admin": "^0.31.0",
48
48
  "@webx-ui/core": "^0.43.0"
49
49
  },
50
50
  "devDependencies": {
@@ -1,377 +0,0 @@
1
- import { defineComponent as B, computed as f, ref as $, onMounted as P, unref as e, openBlock as z, createElementBlock as J, createVNode as c, withCtx as n, createTextVNode as s, toDisplayString as o, createSlots as O, createBlock as V, createElementVNode as l, createCommentVNode as U } from "vue";
2
- import { useAdmin as E, useTranslate as N, useErrorText as D, WxScreen as H, WxListScreen as j } from "@webx-ui/module-admin";
3
- import { toast as I, WxHeading as T, WxCard as R, WxSkeleton as q, WxText as W, WxButton as x, WxIcon as C, WxTabs as F, WxTab as S, WxAlert as G } from "@webx-ui/core";
4
- import { u as L, _ as A, a as K, c as Q } from "./index-BUVSIwLQ.js";
5
- const X = {
6
- key: 0,
7
- class: "wx-content-rules"
8
- }, Y = { class: "wx-content-rules__foot" }, Z = /* @__PURE__ */ B({
9
- __name: "ContentRulesCard",
10
- setup(M) {
11
- const d = E();
12
- L();
13
- const t = N("webx-auth"), m = N("webx-admin"), h = D(), i = f(() => {
14
- const u = d.state.manifest?.modules.find((k) => k.id === "settings")?.meta?.content_screen;
15
- return typeof u == "string" ? u : null;
16
- }), v = d.can("settings.view") || d.can("settings.manage"), y = d.can("settings.manage"), _ = $({}), g = $({}), w = $(!0), b = $(!1), p = `${d.apiPath}/settings/content`;
17
- P(async () => {
18
- if (!(!i.value || !v))
19
- try {
20
- const a = await d.http.get(p);
21
- _.value = a.data.values;
22
- } catch (a) {
23
- I.danger(h(a));
24
- } finally {
25
- w.value = !1;
26
- }
27
- });
28
- async function r() {
29
- b.value = !0, g.value = {};
30
- try {
31
- const a = await d.http.put(p, {
32
- values: _.value
33
- });
34
- _.value = a.data.values, I.success(m("editor.saved"));
35
- } catch (a) {
36
- const u = a.body;
37
- u?.errors && (g.value = u.errors), I.danger(h(a));
38
- } finally {
39
- b.value = !1;
40
- }
41
- }
42
- return (a, u) => i.value && e(v) ? (z(), J("section", X, [
43
- c(e(T), {
44
- level: 2,
45
- size: "sm"
46
- }, {
47
- default: n(() => [
48
- s(o(e(t)("connect.rules")), 1)
49
- ]),
50
- _: 1
51
- }),
52
- c(e(R), null, O({
53
- default: n(() => [
54
- w.value ? (z(), V(e(q), {
55
- key: 0,
56
- rows: 4
57
- })) : (z(), V(e(H), {
58
- key: 1,
59
- modelValue: _.value,
60
- "onUpdate:modelValue": u[0] || (u[0] = (k) => _.value = k),
61
- name: i.value,
62
- errors: g.value,
63
- disabled: !e(y)
64
- }, null, 8, ["modelValue", "name", "errors", "disabled"]))
65
- ]),
66
- _: 2
67
- }, [
68
- w.value ? void 0 : {
69
- name: "footer",
70
- fn: n(() => [
71
- l("div", Y, [
72
- c(e(W), {
73
- size: "sm",
74
- tone: "muted"
75
- }, {
76
- default: n(() => [
77
- s(o(e(t)("connect.rules-hint")), 1)
78
- ]),
79
- _: 1
80
- }),
81
- e(y) ? (z(), V(e(x), {
82
- key: 0,
83
- type: "primary",
84
- loading: b.value,
85
- onClick: r
86
- }, {
87
- default: n(() => [
88
- s(o(e(m)("editor.save")), 1)
89
- ]),
90
- _: 1
91
- }, 8, ["loading"])) : U("", !0)
92
- ])
93
- ]),
94
- key: "0"
95
- }
96
- ]), 1024)
97
- ])) : U("", !0);
98
- }
99
- }), ee = /* @__PURE__ */ A(Z, [["__scopeId", "data-v-55be157e"]]), te = { class: "wx-connect" }, ne = { class: "wx-connect__section" }, ce = { class: "wx-connect__row" }, oe = { class: "wx-connect__url" }, le = { class: "wx-connect__section" }, ae = { class: "wx-connect__steps" }, se = { class: "wx-connect__steps" }, ie = { class: "wx-connect__snippet" }, ue = { class: "wx-connect__snippet" }, re = { class: "wx-connect__section" }, de = { class: "wx-connect__links" }, _e = { class: "wx-connect__steps" }, me = { class: "wx-connect__section" }, ve = /* @__PURE__ */ B({
100
- __name: "ConnectPage",
101
- setup(M) {
102
- const d = E();
103
- L();
104
- const t = N("webx-auth"), m = $(!1);
105
- let h;
106
- const i = f(() => {
107
- const r = d.state.manifest?.modules.find((a) => a.id === "connect")?.meta;
108
- return typeof r?.url == "string" ? r.url : "";
109
- }), v = f(() => {
110
- try {
111
- return new URL(i.value).hostname.split(".")[0] || "webx";
112
- } catch {
113
- return "webx";
114
- }
115
- }), y = f(() => `claude mcp add --transport http ${v.value} ${i.value}`), _ = f(() => `[mcp_servers.${v.value}]
116
- url = "${i.value}"`), g = f(() => {
117
- const r = b(JSON.stringify({ url: i.value }));
118
- return `cursor://anysphere.cursor-deeplink/mcp/install?name=${encodeURIComponent(v.value)}&config=${r}`;
119
- }), w = f(() => {
120
- const r = JSON.stringify({ name: v.value, type: "http", url: i.value });
121
- return `vscode:mcp/install?${encodeURIComponent(r)}`;
122
- });
123
- function b(r) {
124
- const a = new TextEncoder().encode(r);
125
- let u = "";
126
- for (const k of a) u += String.fromCharCode(k);
127
- return encodeURIComponent(btoa(u));
128
- }
129
- async function p(r) {
130
- if (!await Q(r)) {
131
- I.danger(t("connect.copy-failed"));
132
- return;
133
- }
134
- m.value = !0, clearTimeout(h), h = setTimeout(() => m.value = !1, 2e3);
135
- }
136
- return (r, a) => (z(), V(e(j), {
137
- title: e(t)("connect.title"),
138
- card: !1
139
- }, {
140
- default: n(() => [
141
- l("div", te, [
142
- c(e(W), { class: "wx-connect__lead" }, {
143
- default: n(() => [
144
- s(o(e(t)("connect.lead")), 1)
145
- ]),
146
- _: 1
147
- }),
148
- l("section", ne, [
149
- c(e(T), {
150
- level: 2,
151
- size: "sm"
152
- }, {
153
- default: n(() => [
154
- s(o(e(t)("connect.address")), 1)
155
- ]),
156
- _: 1
157
- }),
158
- c(e(R), { bordered: "" }, {
159
- default: n(() => [
160
- l("div", ce, [
161
- l("code", oe, o(i.value), 1),
162
- c(e(x), {
163
- type: "primary",
164
- disabled: i.value === "",
165
- onClick: a[0] || (a[0] = (u) => p(i.value))
166
- }, {
167
- icon: n(() => [
168
- c(e(C), {
169
- name: m.value ? "check" : "copy"
170
- }, null, 8, ["name"])
171
- ]),
172
- default: n(() => [
173
- s(" " + o(m.value ? e(t)("connect.copied") : e(t)("connect.copy")), 1)
174
- ]),
175
- _: 1
176
- }, 8, ["disabled"])
177
- ])
178
- ]),
179
- _: 1
180
- })
181
- ]),
182
- l("section", le, [
183
- c(e(T), {
184
- level: 2,
185
- size: "sm"
186
- }, {
187
- default: n(() => [
188
- s(o(e(t)("connect.how")), 1)
189
- ]),
190
- _: 1
191
- }),
192
- c(e(F), {
193
- variant: "line",
194
- "aria-label": e(t)("connect.how")
195
- }, {
196
- default: n(() => [
197
- c(e(S), {
198
- value: "claude",
199
- label: e(t)("connect.claude-title")
200
- }, {
201
- default: n(() => [
202
- l("ol", ae, [
203
- l("li", null, o(e(t)("connect.claude-1")), 1),
204
- l("li", null, o(e(t)("connect.claude-2")), 1),
205
- l("li", null, o(e(t)("connect.claude-3")), 1)
206
- ])
207
- ]),
208
- _: 1
209
- }, 8, ["label"]),
210
- c(e(S), {
211
- value: "chatgpt",
212
- label: e(t)("connect.chatgpt-title")
213
- }, {
214
- default: n(() => [
215
- l("ol", se, [
216
- l("li", null, o(e(t)("connect.chatgpt-1")), 1),
217
- l("li", null, o(e(t)("connect.chatgpt-2")), 1),
218
- l("li", null, o(e(t)("connect.chatgpt-3")), 1)
219
- ])
220
- ]),
221
- _: 1
222
- }, 8, ["label"]),
223
- c(e(S), {
224
- value: "claude-code",
225
- label: e(t)("connect.claude-code-title")
226
- }, {
227
- default: n(() => [
228
- c(e(W), { size: "sm" }, {
229
- default: n(() => [
230
- s(o(e(t)("connect.claude-code-hint")), 1)
231
- ]),
232
- _: 1
233
- }),
234
- l("div", ie, [
235
- l("pre", null, o(y.value), 1),
236
- c(e(x), {
237
- variant: "text",
238
- size: "sm",
239
- onClick: a[1] || (a[1] = (u) => p(y.value))
240
- }, {
241
- icon: n(() => [
242
- c(e(C), { name: "copy" })
243
- ]),
244
- default: n(() => [
245
- s(" " + o(e(t)("connect.copy-line")), 1)
246
- ]),
247
- _: 1
248
- })
249
- ])
250
- ]),
251
- _: 1
252
- }, 8, ["label"]),
253
- c(e(S), {
254
- value: "codex",
255
- label: e(t)("connect.codex-title")
256
- }, {
257
- default: n(() => [
258
- c(e(W), { size: "sm" }, {
259
- default: n(() => [
260
- s(o(e(t)("connect.codex-hint")), 1)
261
- ]),
262
- _: 1
263
- }),
264
- l("div", ue, [
265
- l("pre", null, o(_.value), 1),
266
- c(e(x), {
267
- variant: "text",
268
- size: "sm",
269
- onClick: a[2] || (a[2] = (u) => p(_.value))
270
- }, {
271
- icon: n(() => [
272
- c(e(C), { name: "copy" })
273
- ]),
274
- default: n(() => [
275
- s(" " + o(e(t)("connect.copy-line")), 1)
276
- ]),
277
- _: 1
278
- })
279
- ])
280
- ]),
281
- _: 1
282
- }, 8, ["label"])
283
- ]),
284
- _: 1
285
- }, 8, ["aria-label"])
286
- ]),
287
- l("section", re, [
288
- c(e(T), {
289
- level: 2,
290
- size: "sm"
291
- }, {
292
- default: n(() => [
293
- s(o(e(t)("connect.one-click")), 1)
294
- ]),
295
- _: 1
296
- }),
297
- c(e(W), {
298
- size: "sm",
299
- tone: "muted"
300
- }, {
301
- default: n(() => [
302
- s(o(e(t)("connect.one-click-hint")), 1)
303
- ]),
304
- _: 1
305
- }),
306
- l("div", de, [
307
- c(e(x), {
308
- href: g.value,
309
- variant: "outline",
310
- disabled: i.value === "",
311
- class: "wx-connect__link"
312
- }, {
313
- icon: n(() => [
314
- c(e(C), { name: "external-link" })
315
- ]),
316
- default: n(() => [
317
- s(" " + o(e(t)("connect.install-in", { client: e(t)("connect.cursor-title") })), 1)
318
- ]),
319
- _: 1
320
- }, 8, ["href", "disabled"]),
321
- c(e(x), {
322
- href: w.value,
323
- variant: "outline",
324
- disabled: i.value === "",
325
- class: "wx-connect__link"
326
- }, {
327
- icon: n(() => [
328
- c(e(C), { name: "external-link" })
329
- ]),
330
- default: n(() => [
331
- s(" " + o(e(t)("connect.install-in", { client: e(t)("connect.vscode-title") })), 1)
332
- ]),
333
- _: 1
334
- }, 8, ["href", "disabled"])
335
- ])
336
- ]),
337
- c(e(G), {
338
- type: "info",
339
- title: e(t)("connect.next")
340
- }, {
341
- default: n(() => [
342
- l("ol", _e, [
343
- l("li", null, o(e(t)("connect.next-1")), 1),
344
- l("li", null, o(e(t)("connect.next-2")), 1),
345
- l("li", null, o(e(t)("connect.next-3")), 1)
346
- ])
347
- ]),
348
- _: 1
349
- }, 8, ["title"]),
350
- c(ee),
351
- l("section", me, [
352
- c(e(T), {
353
- level: 2,
354
- size: "sm"
355
- }, {
356
- default: n(() => [
357
- s(o(e(t)("connect.mine")), 1)
358
- ]),
359
- _: 1
360
- }),
361
- c(e(R), { padding: "none" }, {
362
- default: n(() => [
363
- c(K, { scope: "mine" })
364
- ]),
365
- _: 1
366
- })
367
- ])
368
- ])
369
- ]),
370
- _: 1
371
- }, 8, ["title"]));
372
- }
373
- }), ye = /* @__PURE__ */ A(ve, [["__scopeId", "data-v-19a489e0"]]);
374
- export {
375
- ye as default
376
- };
377
- //# sourceMappingURL=ConnectPage-CGGeG8--.js.map