@oj-module/cli 0.1.21 → 0.2.2
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/devkit/README.md +1 -1
- package/devkit/SKILL.md +17 -3
- package/devkit/manual.md +77 -0
- package/package.json +2 -2
- package/shell-dist/assets/{index-BUyoDvUl.js → index-CLdhl3Qd.js} +61 -12
- package/shell-dist/assets/runtime.js +226 -89
- package/shell-dist/index.html +3 -3
- package/shell-dist/versions.json +3 -3
- package/src/build.ts +25 -0
- package/src/init.ts +3 -0
- package/templates/README.md +54 -0
- package/templates/api/config.yaml +14 -0
- package/templates/api/seed.mysql.sql +5 -0
- package/templates/api/seed.pg.sql +5 -0
- package/templates/api/src/_platform/_shared/respond.ts +18 -0
- package/templates/api/src/_platform/_shared/service/access.ts +99 -0
- package/templates/api/src/_platform/_shared/service/audit.ts +90 -0
- package/templates/api/src/_platform/_shared/service/contacts.ts +36 -0
- package/templates/api/src/_platform/_shared/service/guard.ts +30 -0
- package/templates/api/src/_platform/_shared/service/oplog.ts +47 -0
- package/templates/api/src/_platform/_shared/service/query.ts +53 -0
- package/templates/api/src/_platform/_shared/service/rate.ts +79 -0
- package/templates/api/src/_platform/_shared/service/roles.ts +137 -0
- package/templates/api/src/_platform/_shared/service/settings.ts +67 -0
- package/templates/api/src/_platform/_shared/service/solution-perms.ts +94 -0
- package/templates/api/src/_platform/_shared/service/users.ts +163 -0
- package/templates/api/src/_platform/contacts/api.ts +22 -0
- package/templates/api/src/_platform/contacts/detail/api.ts +18 -0
- package/templates/api/src/_platform/manifest.yaml +9 -1
- package/templates/api/src/_platform/migrations/0001__create_users.mysql.sql +9 -0
- package/templates/api/src/_platform/migrations/0001__create_users.pg.sql +9 -0
- package/templates/api/src/_platform/migrations/0002__add_users_avatar_base64.mysql.sql +3 -0
- package/templates/api/src/_platform/migrations/0003__users_source_display_name.mysql.sql +5 -0
- package/templates/api/src/_platform/migrations/0003__users_source_display_name.sql +5 -0
- package/templates/api/src/_platform/migrations/0004__sys_rbac.mysql.sql +70 -0
- package/templates/api/src/_platform/migrations/0004__sys_rbac.pg.sql +67 -0
- package/templates/api/src/_platform/migrations/0004__sys_rbac.sql +67 -0
- package/templates/api/src/_platform/migrations/0005__users_must_change.mysql.sql +3 -0
- package/templates/api/src/_platform/migrations/0005__users_must_change.sql +2 -0
- package/templates/api/src/_platform/migrations/0006__users_is_forbidden.mysql.sql +3 -0
- package/templates/api/src/_platform/migrations/0006__users_is_forbidden.sql +3 -0
- package/templates/api/src/_platform/migrations/0007__users_email.sql +3 -0
- package/templates/api/src/_platform/migrations/0008__sys_refresh_token.mysql.sql +10 -0
- package/templates/api/src/_platform/migrations/0008__sys_refresh_token.pg.sql +10 -0
- package/templates/api/src/_platform/migrations/0008__sys_refresh_token.sql +11 -0
- package/templates/api/src/_platform/migrations/0009__sys_throttle.mysql.sql +12 -0
- package/templates/api/src/_platform/migrations/0009__sys_throttle.pg.sql +12 -0
- package/templates/api/src/_platform/migrations/0009__sys_throttle.sql +13 -0
- package/templates/api/src/_platform/schema.yaml +76 -1
- package/templates/api/src/_platform/seed.mysql.sql +8 -0
- package/templates/api/src/_platform/seed.pg.sql +8 -0
- package/templates/api/src/_platform/seed.sql +19 -2
- package/templates/api/src/auth/_shared/ldap-login.ts +86 -0
- package/templates/api/src/auth/_shared/ldap.ts +14 -0
- package/templates/api/src/auth/_shared/login-throttle.ts +29 -0
- package/templates/api/src/auth/_shared/session.ts +163 -18
- package/templates/api/src/auth/api.ts +54 -44
- package/templates/api/src/auth/ldap-login/api.ts +29 -0
- package/templates/api/src/system/login-methods/api.ts +19 -0
- package/templates/api/src/system/manifest.yaml +5 -0
- package/templates/api/src/system/oplog/api.ts +53 -0
- package/templates/api/src/system/permissions/api.ts +26 -0
- package/templates/api/src/system/roles/api.ts +75 -0
- package/templates/api/src/system/roles/bindings/api.ts +29 -0
- package/templates/api/src/system/settings/api.ts +60 -0
- package/templates/api/src/system/users/api.ts +58 -0
- package/templates/api/src/system/users/forbidden/api.ts +26 -0
- package/templates/api/src/system/users/password/api.ts +26 -0
- package/templates/api/src/system/users/roles/api.ts +27 -0
- package/templates/api/src/web/user-info/api.ts +9 -18
- package/templates/api/tests/auth-ldap.spec.ts +173 -0
- package/templates/api/tests/auth-session.spec.ts +194 -0
- package/templates/api/tests/auth-throttle.spec.ts +74 -0
- package/templates/api/tests/fixture.ts +50 -0
- package/templates/api/tests/guard.spec.ts +62 -0
- package/templates/api/tests/query-utils.spec.ts +68 -0
- package/templates/api/tests/rbac-audit.spec.ts +105 -0
- package/templates/api/tests/rbac-contacts.spec.ts +85 -0
- package/templates/api/tests/rbac-guard.spec.ts +192 -0
- package/templates/api/tests/rbac-roles.spec.ts +159 -0
- package/templates/api/tests/rbac-seed.spec.ts +54 -0
- package/templates/api/tests/rbac-settings.spec.ts +79 -0
- package/templates/api/tests/rbac-solution-perms.spec.ts +168 -0
- package/templates/api/tests/rbac-tables.spec.ts +63 -0
- package/templates/api/tests/rbac-users.spec.ts +164 -0
- package/templates/api/vitest.config.ts +12 -0
- package/templates/openapi.json +1060 -31
- package/templates/pnpm-workspace.yaml +9 -0
- package/templates/web/src/auth/__client/api.schemas.ts +6 -1
- package/templates/web/src/auth/__client/api.ts +33 -1
- package/templates/web/src/login/entry.ts +17 -0
- package/templates/web/src/login/locales/en-US.json +12 -2
- package/templates/web/src/login/locales/zh-CN.json +12 -2
- package/templates/web/src/login/pages/change-password.tsx +74 -0
- package/templates/web/src/system/__client/api.schemas.ts +150 -0
- package/templates/web/src/system/__client/api.ts +358 -0
- package/templates/web/src/system/entry.ts +90 -0
- package/templates/web/src/system/locales/en-US.json +98 -0
- package/templates/web/src/system/locales/zh-CN.json +98 -0
- package/templates/web/src/system/pages/errors.ts +51 -0
- package/templates/web/src/system/pages/forbidden.tsx +35 -0
- package/templates/web/src/system/pages/login-methods/index.tsx +29 -0
- package/templates/web/src/system/pages/oplog/index.tsx +91 -0
- package/templates/web/src/system/pages/roles/index.tsx +91 -0
- package/templates/web/src/system/pages/settings/index.tsx +106 -0
- package/templates/web/src/system/pages/users/index.tsx +168 -0
- package/templates/web/src/system/pages/users/roles.tsx +68 -0
- package/templates/web.config.ts +8 -0
- package/vendor/host-versions.json +3 -3
|
@@ -3,3 +3,12 @@
|
|
|
3
3
|
# 命令报 ERR_PNPM_IGNORED_BUILDS(0.1.0 发布实测)。
|
|
4
4
|
allowBuilds:
|
|
5
5
|
esbuild: true
|
|
6
|
+
|
|
7
|
+
# @oj-module/cli 经 `catalog:` 拉 @redocly/cli,但 catalog 协议只作用于 workspace
|
|
8
|
+
# 自有 package.json 的依赖,对 cli(外部包)的 catalog: 传递依赖无效;生成工程
|
|
9
|
+
# 不钉的话会漂到 latest,新发布的版本(如 2.64.1,发布当日)会撞本机
|
|
10
|
+
# minimumReleaseAge supply-chain 策略被拒(ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION)。
|
|
11
|
+
# 用 override 钉死到仓库 pnpm-workspace.yaml 的 minimumReleaseAgeExclude 白名单版本
|
|
12
|
+
# 2.51.0(cli 实测通过的区间 ^2.51.0 内,且发布已久、过策略)。
|
|
13
|
+
overrides:
|
|
14
|
+
'@redocly/cli': 2.51.0
|
|
@@ -33,7 +33,7 @@ export function createAuthClient(ctx: ModuleContext) {
|
|
|
33
33
|
}
|
|
34
34
|
ctx.register.apiPrefix(API_PREFIX);
|
|
35
35
|
bindRequest(ctx.utils.request);
|
|
36
|
-
return { authLoginPost, authLogoutPost, authRefreshPost };
|
|
36
|
+
return { authLoginPost, authLogoutPost, authRefreshPost, authPasswordPut, authLdapLoginPost };
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
@@ -108,3 +108,35 @@ export async function authRefreshPost(): Promise<unknown> {
|
|
|
108
108
|
throw await toApiError(e);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
+
|
|
112
|
+
export type AuthPasswordPutBody = z.input<(typeof schemas)["authPasswordPut"]["body"]>;
|
|
113
|
+
|
|
114
|
+
export async function authPasswordPut(body: AuthPasswordPutBody): Promise<unknown> {
|
|
115
|
+
const client = ensureReq();
|
|
116
|
+
try {
|
|
117
|
+
const env = await client.put(`auth/password`, { json: body }).json<OjEnvelope<unknown>>();
|
|
118
|
+
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
119
|
+
if (typeof env.code === "number" && env.code !== 0)
|
|
120
|
+
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
121
|
+
const data = env.data as unknown;
|
|
122
|
+
return data;
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
throw await toApiError(e);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export async function authLdapLoginPost(): Promise<unknown> {
|
|
130
|
+
const client = ensureReq();
|
|
131
|
+
try {
|
|
132
|
+
const env = await client.post(`auth/ldap-login`).json<OjEnvelope<unknown>>();
|
|
133
|
+
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
134
|
+
if (typeof env.code === "number" && env.code !== 0)
|
|
135
|
+
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
136
|
+
const data = env.data as unknown;
|
|
137
|
+
return data;
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
throw await toApiError(e);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -34,6 +34,23 @@ export default defineModule({
|
|
|
34
34
|
},
|
|
35
35
|
],
|
|
36
36
|
},
|
|
37
|
+
{
|
|
38
|
+
// 首登/重置后强制改密(must_change 悬挂期唯一可用写端);
|
|
39
|
+
// 管理面 403 msg=password change required 时也引导至此
|
|
40
|
+
path: "/change-password",
|
|
41
|
+
handle: {
|
|
42
|
+
layout: "fullscreen",
|
|
43
|
+
hideInMenu: true,
|
|
44
|
+
title: "login:page.changePwd.title",
|
|
45
|
+
},
|
|
46
|
+
children: [
|
|
47
|
+
{
|
|
48
|
+
index: true,
|
|
49
|
+
Component: lazy(() => import("./pages/change-password")),
|
|
50
|
+
handle: { title: "login:page.changePwd.title", hideInMenu: true },
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
37
54
|
],
|
|
38
55
|
i18n: {
|
|
39
56
|
"zh-CN": () => import("./locales/zh-CN.json"),
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"page": {
|
|
3
3
|
"title": "Sign in",
|
|
4
|
-
"subtitle": "
|
|
4
|
+
"subtitle": "Please sign in to continue",
|
|
5
5
|
"username": "Username",
|
|
6
6
|
"password": "Password",
|
|
7
7
|
"submit": "Sign in",
|
|
8
|
-
"success": "Signed in"
|
|
8
|
+
"success": "Signed in",
|
|
9
|
+
"changePwd": {
|
|
10
|
+
"title": "Change Password",
|
|
11
|
+
"hint": "After first login or an admin reset, you must change your password before using the system.",
|
|
12
|
+
"old": "Current password",
|
|
13
|
+
"new": "New password",
|
|
14
|
+
"confirm": "Confirm new password",
|
|
15
|
+
"min": "At least 6 characters",
|
|
16
|
+
"mismatch": "Passwords do not match",
|
|
17
|
+
"submit": "Change & sign in again"
|
|
18
|
+
}
|
|
9
19
|
}
|
|
10
20
|
}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"page": {
|
|
3
3
|
"title": "登录",
|
|
4
|
-
"subtitle": "
|
|
4
|
+
"subtitle": "请登录以继续使用系统",
|
|
5
5
|
"username": "用户名",
|
|
6
6
|
"password": "密码",
|
|
7
7
|
"submit": "登 录",
|
|
8
|
-
"success": "登录成功"
|
|
8
|
+
"success": "登录成功",
|
|
9
|
+
"changePwd": {
|
|
10
|
+
"title": "修改密码",
|
|
11
|
+
"hint": "首次登录或管理员重置口令后,需先修改密码才能使用系统。",
|
|
12
|
+
"old": "当前密码",
|
|
13
|
+
"new": "新密码",
|
|
14
|
+
"confirm": "确认新密码",
|
|
15
|
+
"min": "至少 6 位",
|
|
16
|
+
"mismatch": "两次输入的新密码不一致",
|
|
17
|
+
"submit": "修改并重新登录"
|
|
18
|
+
}
|
|
9
19
|
}
|
|
10
20
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { fetchChangePassword } from "@oj-module/runtime";
|
|
2
|
+
|
|
3
|
+
import { Alert, Button, Form, Input, Typography } from "antd";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { useTranslation } from "react-i18next";
|
|
6
|
+
import { useNavigate } from "react-router";
|
|
7
|
+
|
|
8
|
+
interface ChangePwdValues {
|
|
9
|
+
old_password: string
|
|
10
|
+
new_password: string
|
|
11
|
+
confirm: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 首登/重置后强制改密页(AC1-27):must_change 悬挂期唯一可用写端是
|
|
16
|
+
* PUT /api/auth/password(后端对未改密用户拒绝其余全部端点)。登录响应
|
|
17
|
+
* data.user.must_change / 管理面 403 msg 均会引导到此页。走 runtime 全局
|
|
18
|
+
* request 出口(fetchChangePassword)——auth 无 web 模块、无 client 宿。
|
|
19
|
+
*/
|
|
20
|
+
export default function ChangePasswordPage() {
|
|
21
|
+
const { t } = useTranslation();
|
|
22
|
+
const navigate = useNavigate();
|
|
23
|
+
const [error, setError] = useState<string>();
|
|
24
|
+
const [loading, setLoading] = useState(false);
|
|
25
|
+
|
|
26
|
+
async function onFinish(values: ChangePwdValues) {
|
|
27
|
+
setLoading(true);
|
|
28
|
+
setError(undefined);
|
|
29
|
+
try {
|
|
30
|
+
await fetchChangePassword({ old_password: values.old_password, new_password: values.new_password });
|
|
31
|
+
// 改密级联吊销 refresh,旧会话状态陈旧——回登录页重新认证
|
|
32
|
+
navigate("/login");
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
setLoading(false);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<>
|
|
44
|
+
<Typography.Title level={3}>
|
|
45
|
+
{t("login:page.changePwd.title")}
|
|
46
|
+
</Typography.Title>
|
|
47
|
+
<Typography.Paragraph type="secondary">
|
|
48
|
+
{t("login:page.changePwd.hint")}
|
|
49
|
+
</Typography.Paragraph>
|
|
50
|
+
{error && <Alert style={{ marginBottom: 16 }} type="error" message={error} showIcon />}
|
|
51
|
+
<Form<ChangePwdValues> layout="vertical" onFinish={onFinish}>
|
|
52
|
+
<Form.Item name="old_password" label={t("login:page.changePwd.old")} rules={[{ required: true }]}>
|
|
53
|
+
<Input.Password autoFocus />
|
|
54
|
+
</Form.Item>
|
|
55
|
+
<Form.Item name="new_password" label={t("login:page.changePwd.new")} rules={[{ required: true }, { min: 6 }]} extra={t("login:page.changePwd.min")}>
|
|
56
|
+
<Input.Password />
|
|
57
|
+
</Form.Item>
|
|
58
|
+
<Form.Item
|
|
59
|
+
name="confirm"
|
|
60
|
+
label={t("login:page.changePwd.confirm")}
|
|
61
|
+
dependencies={["new_password"]}
|
|
62
|
+
rules={[{ required: true }, ({ getFieldValue }) => ({
|
|
63
|
+
validator: (_, value) => value === getFieldValue("new_password") ? Promise.resolve() : Promise.reject(new Error(t("login:page.changePwd.mismatch"))),
|
|
64
|
+
})]}
|
|
65
|
+
>
|
|
66
|
+
<Input.Password />
|
|
67
|
+
</Form.Item>
|
|
68
|
+
<Button type="primary" htmlType="submit" block loading={loading}>
|
|
69
|
+
{t("login:page.changePwd.submit")}
|
|
70
|
+
</Button>
|
|
71
|
+
</Form>
|
|
72
|
+
</>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// 生成物:ojm api 从契约生成,勿手改(改动请改契约文件后重跑 ojm api)
|
|
3
|
+
// AC-D15:仅供 DEV 校验动态 import,生产构建不进产物
|
|
4
|
+
import { z } from "@oj-module/runtime";
|
|
5
|
+
|
|
6
|
+
export const schemas = {
|
|
7
|
+
"systemLoginMethodsGet": {
|
|
8
|
+
data: z.object({
|
|
9
|
+
"methods": z.array(z.string())
|
|
10
|
+
}),
|
|
11
|
+
},
|
|
12
|
+
"systemOplogGet": {
|
|
13
|
+
query: z.object({
|
|
14
|
+
"action": z.string().optional(),
|
|
15
|
+
"username": z.string().optional(),
|
|
16
|
+
"module": z.string().optional(),
|
|
17
|
+
"limit": z.number().min(1).max(200).optional()
|
|
18
|
+
}),
|
|
19
|
+
data: z.object({
|
|
20
|
+
"list": z.array(z.object({
|
|
21
|
+
"id": z.number(),
|
|
22
|
+
"create_time": z.number(),
|
|
23
|
+
"user_id": z.number(),
|
|
24
|
+
"username": z.string(),
|
|
25
|
+
"action": z.string(),
|
|
26
|
+
"module": z.string(),
|
|
27
|
+
"version": z.string().nullable(),
|
|
28
|
+
"target": z.string().nullable(),
|
|
29
|
+
"detail": z.string().nullable(),
|
|
30
|
+
"level": z.number()
|
|
31
|
+
})),
|
|
32
|
+
"total": z.number(),
|
|
33
|
+
"truncated": z.boolean()
|
|
34
|
+
}),
|
|
35
|
+
},
|
|
36
|
+
"systemPermissionsGet": {
|
|
37
|
+
data: z.array(z.object({
|
|
38
|
+
"code": z.string(),
|
|
39
|
+
"module": z.string(),
|
|
40
|
+
"title_key": z.string().nullable(),
|
|
41
|
+
"deprecated": z.boolean()
|
|
42
|
+
})),
|
|
43
|
+
},
|
|
44
|
+
"systemRolesGet": {
|
|
45
|
+
data: z.array(z.object({
|
|
46
|
+
"name": z.string(),
|
|
47
|
+
"module": z.string(),
|
|
48
|
+
"title": z.string().nullable(),
|
|
49
|
+
"description": z.string().nullable(),
|
|
50
|
+
"builtin": z.boolean(),
|
|
51
|
+
"deprecated": z.boolean(),
|
|
52
|
+
"holders": z.number(),
|
|
53
|
+
"permissions": z.array(z.string())
|
|
54
|
+
})),
|
|
55
|
+
},
|
|
56
|
+
"systemRolesPost": {
|
|
57
|
+
body: z.object({
|
|
58
|
+
"name": // @oj-warn: pattern="^custom\\.[a-z0-9][a-z0-9-]*$" 为 Rust regex,未在前端执行(跨语言语义漂移/ReDoS 风险)
|
|
59
|
+
z.string(),
|
|
60
|
+
"title": z.string().min(1),
|
|
61
|
+
"permissions": z.array(z.string()).optional()
|
|
62
|
+
}),
|
|
63
|
+
data: z.object({
|
|
64
|
+
"name": z.string(),
|
|
65
|
+
"module": z.string()
|
|
66
|
+
}),
|
|
67
|
+
},
|
|
68
|
+
"systemRolesDelete": {
|
|
69
|
+
query: z.object({
|
|
70
|
+
"name": z.string().min(1)
|
|
71
|
+
}),
|
|
72
|
+
},
|
|
73
|
+
"systemRolesBindingsPut": {
|
|
74
|
+
query: z.object({
|
|
75
|
+
"name": z.string().min(1)
|
|
76
|
+
}),
|
|
77
|
+
body: z.object({
|
|
78
|
+
"permissions": z.array(z.string())
|
|
79
|
+
}),
|
|
80
|
+
},
|
|
81
|
+
"systemSettingsGet": {
|
|
82
|
+
data: z.array(z.object({
|
|
83
|
+
"group": z.string(),
|
|
84
|
+
"items": z.array(z.object({
|
|
85
|
+
"key": z.string(),
|
|
86
|
+
"module": z.string(),
|
|
87
|
+
"group": z.string(),
|
|
88
|
+
"type": z.string(),
|
|
89
|
+
"value": z.string().nullable(),
|
|
90
|
+
"default_value": z.string().nullable(),
|
|
91
|
+
"label_key": z.string().nullable(),
|
|
92
|
+
"options": z.string().nullable(),
|
|
93
|
+
"secret": z.boolean(),
|
|
94
|
+
"update_time": z.number()
|
|
95
|
+
}))
|
|
96
|
+
})),
|
|
97
|
+
},
|
|
98
|
+
"systemSettingsPut": {
|
|
99
|
+
body: z.object({
|
|
100
|
+
"key": z.string().min(1),
|
|
101
|
+
"value": z.string()
|
|
102
|
+
}),
|
|
103
|
+
},
|
|
104
|
+
"systemUsersGet": {
|
|
105
|
+
data: z.array(z.object({
|
|
106
|
+
"id": z.number(),
|
|
107
|
+
"username": z.string(),
|
|
108
|
+
"display_name": z.string().nullable(),
|
|
109
|
+
"email": z.string().nullable(),
|
|
110
|
+
"is_forbidden": z.boolean(),
|
|
111
|
+
"must_change": z.boolean(),
|
|
112
|
+
"roles": z.array(z.string())
|
|
113
|
+
})),
|
|
114
|
+
},
|
|
115
|
+
"systemUsersPost": {
|
|
116
|
+
body: z.object({
|
|
117
|
+
"username": z.string().min(1),
|
|
118
|
+
"password": z.string().min(6),
|
|
119
|
+
"displayName": z.string().optional(),
|
|
120
|
+
"email": z.string().optional()
|
|
121
|
+
}),
|
|
122
|
+
data: z.object({
|
|
123
|
+
"id": z.number()
|
|
124
|
+
}),
|
|
125
|
+
},
|
|
126
|
+
"systemUsersForbiddenPut": {
|
|
127
|
+
query: z.object({
|
|
128
|
+
"uid": z.number()
|
|
129
|
+
}),
|
|
130
|
+
body: z.object({
|
|
131
|
+
"forbidden": z.boolean()
|
|
132
|
+
}),
|
|
133
|
+
},
|
|
134
|
+
"systemUsersPasswordPut": {
|
|
135
|
+
query: z.object({
|
|
136
|
+
"uid": z.number()
|
|
137
|
+
}),
|
|
138
|
+
body: z.object({
|
|
139
|
+
"password": z.string().min(6)
|
|
140
|
+
}),
|
|
141
|
+
},
|
|
142
|
+
"systemUsersRolesPut": {
|
|
143
|
+
query: z.object({
|
|
144
|
+
"uid": z.number()
|
|
145
|
+
}),
|
|
146
|
+
body: z.object({
|
|
147
|
+
"roles": z.array(z.string())
|
|
148
|
+
}),
|
|
149
|
+
},
|
|
150
|
+
};
|