@h-ai/serv 0.1.0-alpha.75 → 1.0.0-beta.1
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/README.en.md +22 -9
- package/README.ja.md +22 -9
- package/README.md +22 -9
- package/dist/{chunk-JAQIEQJS.js → chunk-I3F7RN4I.js} +8 -2
- package/dist/chunk-I3F7RN4I.js.map +1 -0
- package/dist/{chunk-65XNI7TH.js → chunk-TWMOZPGU.js} +3 -3
- package/dist/{chunk-65XNI7TH.js.map → chunk-TWMOZPGU.js.map} +1 -1
- package/dist/features/ai.js +1 -1
- package/dist/features/feedback.js +1 -1
- package/dist/features/iam.d.ts +42 -44
- package/dist/features/iam.js +1 -9
- package/dist/features/iam.js.map +1 -1
- package/dist/features/storage.js +2 -2
- package/dist/index.d.ts +85 -13
- package/dist/index.js +154 -157
- package/dist/index.js.map +1 -1
- package/package.json +16 -16
- package/dist/chunk-JAQIEQJS.js.map +0 -1
package/dist/features/iam.d.ts
CHANGED
|
@@ -225,16 +225,15 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
225
225
|
phone: zod.ZodOptional<zod.ZodString>;
|
|
226
226
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
227
227
|
avatarUrl: zod.ZodOptional<zod.ZodString>;
|
|
228
|
-
enabled: zod.ZodBoolean;
|
|
229
228
|
accountType: zod.ZodOptional<zod.ZodEnum<{
|
|
230
229
|
permanent: "permanent";
|
|
231
230
|
temporary: "temporary";
|
|
232
231
|
}>>;
|
|
233
|
-
accountStatus: zod.
|
|
232
|
+
accountStatus: zod.ZodEnum<{
|
|
234
233
|
active: "active";
|
|
235
234
|
dormant: "dormant";
|
|
236
235
|
closed: "closed";
|
|
237
|
-
}
|
|
236
|
+
}>;
|
|
238
237
|
accountExpiresAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
239
238
|
lastLoginAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
240
239
|
mustChangePassword: zod.ZodOptional<zod.ZodBoolean>;
|
|
@@ -330,16 +329,15 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
330
329
|
phone: zod.ZodOptional<zod.ZodString>;
|
|
331
330
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
332
331
|
avatarUrl: zod.ZodOptional<zod.ZodString>;
|
|
333
|
-
enabled: zod.ZodBoolean;
|
|
334
332
|
accountType: zod.ZodOptional<zod.ZodEnum<{
|
|
335
333
|
permanent: "permanent";
|
|
336
334
|
temporary: "temporary";
|
|
337
335
|
}>>;
|
|
338
|
-
accountStatus: zod.
|
|
336
|
+
accountStatus: zod.ZodEnum<{
|
|
339
337
|
active: "active";
|
|
340
338
|
dormant: "dormant";
|
|
341
339
|
closed: "closed";
|
|
342
|
-
}
|
|
340
|
+
}>;
|
|
343
341
|
accountExpiresAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
344
342
|
lastLoginAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
345
343
|
mustChangePassword: zod.ZodOptional<zod.ZodBoolean>;
|
|
@@ -395,16 +393,15 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
395
393
|
phone: zod.ZodOptional<zod.ZodString>;
|
|
396
394
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
397
395
|
avatarUrl: zod.ZodOptional<zod.ZodString>;
|
|
398
|
-
enabled: zod.ZodBoolean;
|
|
399
396
|
accountType: zod.ZodOptional<zod.ZodEnum<{
|
|
400
397
|
permanent: "permanent";
|
|
401
398
|
temporary: "temporary";
|
|
402
399
|
}>>;
|
|
403
|
-
accountStatus: zod.
|
|
400
|
+
accountStatus: zod.ZodEnum<{
|
|
404
401
|
active: "active";
|
|
405
402
|
dormant: "dormant";
|
|
406
403
|
closed: "closed";
|
|
407
|
-
}
|
|
404
|
+
}>;
|
|
408
405
|
accountExpiresAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
409
406
|
lastLoginAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
410
407
|
mustChangePassword: zod.ZodOptional<zod.ZodBoolean>;
|
|
@@ -492,16 +489,15 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
492
489
|
phone: zod.ZodOptional<zod.ZodString>;
|
|
493
490
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
494
491
|
avatarUrl: zod.ZodOptional<zod.ZodString>;
|
|
495
|
-
enabled: zod.ZodBoolean;
|
|
496
492
|
accountType: zod.ZodOptional<zod.ZodEnum<{
|
|
497
493
|
permanent: "permanent";
|
|
498
494
|
temporary: "temporary";
|
|
499
495
|
}>>;
|
|
500
|
-
accountStatus: zod.
|
|
496
|
+
accountStatus: zod.ZodEnum<{
|
|
501
497
|
active: "active";
|
|
502
498
|
dormant: "dormant";
|
|
503
499
|
closed: "closed";
|
|
504
|
-
}
|
|
500
|
+
}>;
|
|
505
501
|
accountExpiresAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
506
502
|
lastLoginAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
507
503
|
mustChangePassword: zod.ZodOptional<zod.ZodBoolean>;
|
|
@@ -593,16 +589,15 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
593
589
|
phone: zod.ZodOptional<zod.ZodString>;
|
|
594
590
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
595
591
|
avatarUrl: zod.ZodOptional<zod.ZodString>;
|
|
596
|
-
enabled: zod.ZodBoolean;
|
|
597
592
|
accountType: zod.ZodOptional<zod.ZodEnum<{
|
|
598
593
|
permanent: "permanent";
|
|
599
594
|
temporary: "temporary";
|
|
600
595
|
}>>;
|
|
601
|
-
accountStatus: zod.
|
|
596
|
+
accountStatus: zod.ZodEnum<{
|
|
602
597
|
active: "active";
|
|
603
598
|
dormant: "dormant";
|
|
604
599
|
closed: "closed";
|
|
605
|
-
}
|
|
600
|
+
}>;
|
|
606
601
|
accountExpiresAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
607
602
|
lastLoginAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
608
603
|
mustChangePassword: zod.ZodOptional<zod.ZodBoolean>;
|
|
@@ -679,16 +674,15 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
679
674
|
phone: zod.ZodOptional<zod.ZodString>;
|
|
680
675
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
681
676
|
avatarUrl: zod.ZodOptional<zod.ZodString>;
|
|
682
|
-
enabled: zod.ZodBoolean;
|
|
683
677
|
accountType: zod.ZodOptional<zod.ZodEnum<{
|
|
684
678
|
permanent: "permanent";
|
|
685
679
|
temporary: "temporary";
|
|
686
680
|
}>>;
|
|
687
|
-
accountStatus: zod.
|
|
681
|
+
accountStatus: zod.ZodEnum<{
|
|
688
682
|
active: "active";
|
|
689
683
|
dormant: "dormant";
|
|
690
684
|
closed: "closed";
|
|
691
|
-
}
|
|
685
|
+
}>;
|
|
692
686
|
accountExpiresAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
693
687
|
lastLoginAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
694
688
|
mustChangePassword: zod.ZodOptional<zod.ZodBoolean>;
|
|
@@ -726,9 +720,8 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
726
720
|
}>>;
|
|
727
721
|
accountExpiresAt: zod.ZodOptional<zod.ZodCoercedDate<unknown>>;
|
|
728
722
|
roleIds: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
|
|
729
|
-
enabled: zod.ZodOptional<zod.ZodLiteral<true>>;
|
|
730
723
|
accountStatus: zod.ZodOptional<zod.ZodLiteral<"active">>;
|
|
731
|
-
}, zod_v4_core.$
|
|
724
|
+
}, zod_v4_core.$strict>, zod.ZodDiscriminatedUnion<[zod.ZodObject<{
|
|
732
725
|
success: zod.ZodLiteral<true>;
|
|
733
726
|
data: zod.ZodObject<{
|
|
734
727
|
id: zod.ZodString;
|
|
@@ -737,16 +730,15 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
737
730
|
phone: zod.ZodOptional<zod.ZodString>;
|
|
738
731
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
739
732
|
avatarUrl: zod.ZodOptional<zod.ZodString>;
|
|
740
|
-
enabled: zod.ZodBoolean;
|
|
741
733
|
accountType: zod.ZodOptional<zod.ZodEnum<{
|
|
742
734
|
permanent: "permanent";
|
|
743
735
|
temporary: "temporary";
|
|
744
736
|
}>>;
|
|
745
|
-
accountStatus: zod.
|
|
737
|
+
accountStatus: zod.ZodEnum<{
|
|
746
738
|
active: "active";
|
|
747
739
|
dormant: "dormant";
|
|
748
740
|
closed: "closed";
|
|
749
|
-
}
|
|
741
|
+
}>;
|
|
750
742
|
accountExpiresAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
751
743
|
lastLoginAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
752
744
|
mustChangePassword: zod.ZodOptional<zod.ZodBoolean>;
|
|
@@ -773,13 +765,25 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
773
765
|
list: _orpc_server.Procedure<ServContext & {}, any, zod.ZodObject<{
|
|
774
766
|
page: zod.ZodOptional<zod.ZodCoercedNumber<unknown>>;
|
|
775
767
|
pageSize: zod.ZodOptional<zod.ZodCoercedNumber<unknown>>;
|
|
768
|
+
sortBy: zod.ZodOptional<zod.ZodEnum<{
|
|
769
|
+
createdAt: "createdAt";
|
|
770
|
+
email: "email";
|
|
771
|
+
username: "username";
|
|
772
|
+
displayName: "displayName";
|
|
773
|
+
accountStatus: "accountStatus";
|
|
774
|
+
}>>;
|
|
775
|
+
sortDirection: zod.ZodOptional<zod.ZodEnum<{
|
|
776
|
+
asc: "asc";
|
|
777
|
+
desc: "desc";
|
|
778
|
+
}>>;
|
|
776
779
|
roleCode: zod.ZodOptional<zod.ZodString>;
|
|
777
780
|
search: zod.ZodOptional<zod.ZodString>;
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
781
|
+
accountStatus: zod.ZodOptional<zod.ZodEnum<{
|
|
782
|
+
active: "active";
|
|
783
|
+
dormant: "dormant";
|
|
784
|
+
closed: "closed";
|
|
785
|
+
}>>;
|
|
786
|
+
}, zod_v4_core.$strict>, zod.ZodDiscriminatedUnion<[zod.ZodObject<{
|
|
783
787
|
success: zod.ZodLiteral<true>;
|
|
784
788
|
data: zod.ZodObject<{
|
|
785
789
|
items: zod.ZodArray<zod.ZodObject<{
|
|
@@ -789,16 +793,15 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
789
793
|
phone: zod.ZodOptional<zod.ZodString>;
|
|
790
794
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
791
795
|
avatarUrl: zod.ZodOptional<zod.ZodString>;
|
|
792
|
-
enabled: zod.ZodBoolean;
|
|
793
796
|
accountType: zod.ZodOptional<zod.ZodEnum<{
|
|
794
797
|
permanent: "permanent";
|
|
795
798
|
temporary: "temporary";
|
|
796
799
|
}>>;
|
|
797
|
-
accountStatus: zod.
|
|
800
|
+
accountStatus: zod.ZodEnum<{
|
|
798
801
|
active: "active";
|
|
799
802
|
dormant: "dormant";
|
|
800
803
|
closed: "closed";
|
|
801
|
-
}
|
|
804
|
+
}>;
|
|
802
805
|
accountExpiresAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
803
806
|
lastLoginAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
804
807
|
mustChangePassword: zod.ZodOptional<zod.ZodBoolean>;
|
|
@@ -837,16 +840,15 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
837
840
|
phone: zod.ZodOptional<zod.ZodString>;
|
|
838
841
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
839
842
|
avatarUrl: zod.ZodOptional<zod.ZodString>;
|
|
840
|
-
enabled: zod.ZodBoolean;
|
|
841
843
|
accountType: zod.ZodOptional<zod.ZodEnum<{
|
|
842
844
|
permanent: "permanent";
|
|
843
845
|
temporary: "temporary";
|
|
844
846
|
}>>;
|
|
845
|
-
accountStatus: zod.
|
|
847
|
+
accountStatus: zod.ZodEnum<{
|
|
846
848
|
active: "active";
|
|
847
849
|
dormant: "dormant";
|
|
848
850
|
closed: "closed";
|
|
849
|
-
}
|
|
851
|
+
}>;
|
|
850
852
|
accountExpiresAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
851
853
|
lastLoginAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
852
854
|
mustChangePassword: zod.ZodOptional<zod.ZodBoolean>;
|
|
@@ -888,8 +890,7 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
888
890
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
889
891
|
metadata: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodUnknown>>;
|
|
890
892
|
roleIds: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
|
|
891
|
-
|
|
892
|
-
}, zod_v4_core.$strip>, zod.ZodDiscriminatedUnion<[zod.ZodObject<{
|
|
893
|
+
}, zod_v4_core.$strict>, zod.ZodDiscriminatedUnion<[zod.ZodObject<{
|
|
893
894
|
success: zod.ZodLiteral<true>;
|
|
894
895
|
data: zod.ZodObject<{
|
|
895
896
|
id: zod.ZodString;
|
|
@@ -898,16 +899,15 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
898
899
|
phone: zod.ZodOptional<zod.ZodString>;
|
|
899
900
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
900
901
|
avatarUrl: zod.ZodOptional<zod.ZodString>;
|
|
901
|
-
enabled: zod.ZodBoolean;
|
|
902
902
|
accountType: zod.ZodOptional<zod.ZodEnum<{
|
|
903
903
|
permanent: "permanent";
|
|
904
904
|
temporary: "temporary";
|
|
905
905
|
}>>;
|
|
906
|
-
accountStatus: zod.
|
|
906
|
+
accountStatus: zod.ZodEnum<{
|
|
907
907
|
active: "active";
|
|
908
908
|
dormant: "dormant";
|
|
909
909
|
closed: "closed";
|
|
910
|
-
}
|
|
910
|
+
}>;
|
|
911
911
|
accountExpiresAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
912
912
|
lastLoginAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
913
913
|
mustChangePassword: zod.ZodOptional<zod.ZodBoolean>;
|
|
@@ -949,9 +949,8 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
949
949
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
950
950
|
avatarUrl: zod.ZodOptional<zod.ZodString>;
|
|
951
951
|
metadata: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodUnknown>>;
|
|
952
|
-
enabled: zod.ZodOptional<zod.ZodBoolean>;
|
|
953
952
|
roleIds: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
|
|
954
|
-
}, zod_v4_core.$
|
|
953
|
+
}, zod_v4_core.$strict>, zod.ZodDiscriminatedUnion<[zod.ZodObject<{
|
|
955
954
|
success: zod.ZodLiteral<true>;
|
|
956
955
|
data: zod.ZodObject<{
|
|
957
956
|
id: zod.ZodString;
|
|
@@ -960,16 +959,15 @@ declare function createIamProcedures(deps: IamProcedureDeps): {
|
|
|
960
959
|
phone: zod.ZodOptional<zod.ZodString>;
|
|
961
960
|
displayName: zod.ZodOptional<zod.ZodString>;
|
|
962
961
|
avatarUrl: zod.ZodOptional<zod.ZodString>;
|
|
963
|
-
enabled: zod.ZodBoolean;
|
|
964
962
|
accountType: zod.ZodOptional<zod.ZodEnum<{
|
|
965
963
|
permanent: "permanent";
|
|
966
964
|
temporary: "temporary";
|
|
967
965
|
}>>;
|
|
968
|
-
accountStatus: zod.
|
|
966
|
+
accountStatus: zod.ZodEnum<{
|
|
969
967
|
active: "active";
|
|
970
968
|
dormant: "dormant";
|
|
971
969
|
closed: "closed";
|
|
972
|
-
}
|
|
970
|
+
}>;
|
|
973
971
|
accountExpiresAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
974
972
|
lastLoginAt: zod.ZodOptional<zod.ZodNullable<zod.ZodCoercedDate<unknown>>>;
|
|
975
973
|
mustChangePassword: zod.ZodOptional<zod.ZodBoolean>;
|
package/dist/features/iam.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mapHaiResult } from '../chunk-XKCLD42I.js';
|
|
2
|
-
import { implement, servM } from '../chunk-
|
|
2
|
+
import { implement, servM } from '../chunk-I3F7RN4I.js';
|
|
3
3
|
import { apiContract } from '@h-ai/api-contract';
|
|
4
4
|
import { core, err, HaiCommonError, ok } from '@h-ai/core';
|
|
5
5
|
|
|
@@ -89,14 +89,6 @@ async function createUser(iam, input) {
|
|
|
89
89
|
return rolesResult;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
-
if (input.enabled === false) {
|
|
93
|
-
const updateResult = await iam.user.updateUser(userId, { enabled: false });
|
|
94
|
-
if (!updateResult.success) {
|
|
95
|
-
await rollback("initial disable failed");
|
|
96
|
-
return updateResult;
|
|
97
|
-
}
|
|
98
|
-
return updateResult;
|
|
99
|
-
}
|
|
100
92
|
return ok(registerResult.data.user);
|
|
101
93
|
}
|
|
102
94
|
async function updateUser(iam, input) {
|
package/dist/features/iam.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/features/serv-feature-iam.ts"],"names":[],"mappings":"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","file":"iam.js","sourcesContent":["/**\n * @h-ai/serv — IAM 默认 procedures\n *\n * 基于 `@h-ai/iam` 提供开箱即用的 IAM procedures 实现:认证、用户管理、角色权限 CRUD。\n * @module features/serv-feature-iam\n */\n\nimport type {\n IamAdminCreateUserInput,\n IamAdminUpdateUserInput,\n IamCurrentUser,\n IamInviteUserInput,\n} from '@h-ai/api-contract'\nimport type { HaiResult } from '@h-ai/core'\nimport type { IamFunctions, TokenPair, User } from '@h-ai/iam'\nimport type { ServContext } from '../serv-context.js'\nimport { apiContract } from '@h-ai/api-contract'\nimport { core, err, HaiCommonError, ok } from '@h-ai/core'\nimport { servM } from '../serv-i18n.js'\nimport { implement } from '../serv-router.js'\nimport { mapHaiResult } from './serv-feature-helpers.js'\n\nconst iamContract = apiContract.iam\n\nconst iamFeatureLogger = core.logger.child({ module: 'serv', scope: 'feature-iam' })\n\n/**\n * IAM 默认 procedures 依赖。\n *\n * @example\n * ```ts\n * import { iam } from '@h-ai/iam'\n * import { createIamProcedures } from '@h-ai/serv/features/iam'\n *\n * // 宿主已初始化 IAM 及共享依赖。\n * const procedures = createIamProcedures({ iam })\n * // logout 撤销请求持有的 opaque access token;过期 access 也可撤销 refresh,\n * // 不接收 userId,不要求有效 access 的 auth guard,失败仍检查 HaiResult。\n * ```\n */\nexport interface IamProcedureDeps {\n readonly iam: IamFunctions\n}\n\n/**\n * 创建默认 IAM procedures;按操作声明认证/权限。logout 只撤销请求持有的完整 opaque token,不要求该 access 尚有效,也不能按 userId 撤销。\n *\n * @example\n * ```ts\n * import { iam } from '@h-ai/iam'\n * import { createIamProcedures } from '@h-ai/serv/features/iam'\n *\n * // 宿主已初始化 IAM 及共享依赖。\n * const procedures = createIamProcedures({ iam })\n * // logout 撤销请求持有的 opaque access token;过期 access 也可撤销 refresh,\n * // 不接收 userId,不要求有效 access 的 auth guard,失败仍检查 HaiResult。\n * ```\n */\nexport function createIamProcedures(deps: IamProcedureDeps) {\n const { iam } = deps\n\n // 权限守卫先执行;额外鉴别只绑定已授权操作,不提升原有权限。\n async function sensitive<T>(context: ServContext, operation: string, run: () => Promise<HaiResult<T>>): Promise<HaiResult<T>> {\n const policy = iam.publicConfig?.reauthentication\n if (policy?.enabled) {\n const checked = await iam.auth.checkSensitiveOperation(context.accessToken ?? '', operation, context.request.headers.get('x-hai-reauthentication') ?? undefined)\n if (!checked.success)\n return checked\n }\n return run()\n }\n\n return implement(iamContract)\n .context<ServContext>()\n\n .route('auth.reauthenticate')\n .auth()\n .handle(({ input, context }) => iam.auth.reauthenticate(context.accessToken ?? '', input.password, input.operation))\n\n .route('auth.login', ({ input, context }) => iam.auth.login(input, context))\n .route('auth.createCaptcha', ({ input }) => iam.auth.createCaptcha(input))\n .route('auth.loginWithOtp', ({ input, context }) => iam.auth.loginWithOtp(input, context))\n .route('auth.loginWithLdap', ({ input, context }) => iam.auth.loginWithLdap(input, context))\n .route('auth.publicConfig', () => iam.getPublicConfig())\n .route('auth.renewPassword', ({ input }) => iam.user.renewPassword(input))\n .route('auth.requestPasswordReset', ({ input }) => iam.user.requestPasswordReset(input.identifier, input))\n .route('auth.confirmPasswordReset', ({ input }) => iam.user.confirmPasswordReset(input.token, input.newPassword))\n\n .route('auth.logout', ({ input, context }) => {\n // 仅撤销调用方持有的完整随机令牌;不要求 access 仍有效,也不接受 userId 撤销。\n const token = input.accessToken ?? context.accessToken\n if (!token)\n return err(HaiCommonError.UNAUTHORIZED, servM('serv_errorUnauthorized', { locale: context.locale }))\n return iam.auth.logout(token)\n })\n\n .route('auth.closeSession', ({ input, context }) => {\n // 页面离开只撤销持有的会话,不清 Cookie,避免迟到响应覆盖下一文档的新登录。\n const token = input.accessToken ?? context.accessToken\n if (!token)\n return err(HaiCommonError.UNAUTHORIZED, servM('serv_errorUnauthorized', { locale: context.locale }))\n return iam.auth.logout(token)\n })\n\n .route('auth.currentUser')\n .auth()\n .handle(async ({ context }) => {\n const token = context.accessToken\n if (!token)\n return err(HaiCommonError.UNAUTHORIZED, servM('serv_errorUnauthorized', { locale: context.locale }))\n\n return mapHaiResult<User, IamCurrentUser>(\n await iam.user.getCurrentUser(token),\n user => ({\n ...user,\n roles: context.session.roles,\n permissions: context.session.permissions,\n }),\n )\n })\n\n .route('auth.refresh', async ({ input }) => {\n return mapHaiResult(await iam.session.refresh(input.refreshToken), tokens => ({ tokens }))\n })\n .route('auth.sendOtp', ({ input }) => iam.auth.sendOtp(input.identifier, input))\n .route('auth.register', ({ input, context }) => iam.auth.registerAndLogin(input, context))\n\n .route('auth.changePassword')\n .auth()\n .handle(({ input, context }) => {\n const token = context.accessToken\n if (!token)\n return err(HaiCommonError.UNAUTHORIZED, servM('serv_errorUnauthorized', { locale: context.locale }))\n return iam.user.changeCurrentUserPassword(token, input.oldPassword, input.newPassword)\n })\n\n .route('auth.updateCurrentUser')\n .auth()\n .handle(async ({ input, context }) => {\n const token = context.accessToken\n if (!token)\n return err(HaiCommonError.UNAUTHORIZED, servM('serv_errorUnauthorized', { locale: context.locale }))\n const policy = await iam.getPublicConfig()\n if (!policy.success)\n return policy\n // 标准资料入口与独立资料/头像入口共用策略;混合更新优先使用资料用途。\n const operations = [\n ...(Object.keys(input).some(key => key !== 'avatarUrl') ? ['iam.profile.update'] : []),\n ...(input.avatarUrl !== undefined ? ['iam.profile.avatar'] : []),\n ]\n const operation = operations.find(value => policy.data.reauthentication.operations.includes(value)) ?? operations[0] ?? 'iam.profile.update'\n return sensitive(context, operation, () => iam.user.updateCurrentUser(token, input))\n })\n\n .route('users.list')\n .permission('iam.users.read')\n .handle(({ input }) => iam.user.listUsers(input))\n\n .route('users.get')\n .permission('iam.users.read')\n .handle(({ input }) => iam.user.getUser(input.id, { include: ['roles'] }))\n\n .route('users.create')\n .permission('iam.users.write')\n .handle(({ input, context }) => sensitive(context, 'iam.users.create', () => createUser(iam, input)))\n\n .route('users.invite')\n .permission('iam.users.write')\n .handle(({ input, context }) => sensitive(context, 'iam.users.invite', () => createUser(iam, input)))\n\n .route('users.update')\n .permission('iam.users.write')\n .handle(({ input, context }) => sensitive(context, 'iam.users.update', () => updateUser(iam, input)))\n\n .route('users.delete')\n .permission('iam.users.write')\n .handle(({ input, context }) => {\n // 防止自删:避免管理员误删自己的账号导致授权锁死。\n if (context.session.userId === input.id)\n return err(HaiCommonError.FORBIDDEN, servM('serv_iamCannotDeleteCurrentUser', { locale: context.locale }))\n return sensitive(context, 'iam.users.delete', () => iam.user.deleteUser(input.id))\n })\n\n .route('users.resetPassword')\n .permission('iam.users.write')\n .handle(({ input, context }) => sensitive(context, 'iam.users.resetPassword', () => iam.user.adminResetPassword(input.id, input.newPassword)))\n\n .route('roles.list')\n .permission('iam.roles.read')\n .handle(() => iam.authz.getAllRoles())\n\n .route('roles.get')\n .permission('iam.roles.read')\n .handle(({ input }) => iam.authz.getRole(input.id))\n\n .route('roles.create')\n .permission('iam.roles.write')\n .handle(({ input, context }) => sensitive(context, 'iam.roles.create', () => iam.authz.createRole(input)))\n\n .route('roles.update')\n .permission('iam.roles.write')\n .handle(({ input, context }) => {\n const { id, ...data } = input\n return sensitive(context, 'iam.roles.update', () => iam.authz.updateRole(id, data))\n })\n\n .route('roles.delete')\n .permission('iam.roles.write')\n .handle(({ input, context }) => sensitive(context, 'iam.roles.delete', () => iam.authz.deleteRole(input.id)))\n\n .route('permissions.list')\n .permission('iam.permissions.read')\n .handle(({ input }) => iam.authz.getAllPermissions(input))\n\n .route('permissions.get')\n .permission('iam.permissions.read')\n .handle(({ input }) => iam.authz.getPermission(input.id))\n\n .route('permissions.create')\n .permission('iam.permissions.write')\n .handle(({ input, context }) => sensitive(context, 'iam.permissions.create', () => iam.authz.createPermission(input)))\n\n .route('permissions.setSensitiveOperations')\n .permission('iam.permissions.write')\n .handle(({ input, context }) => sensitive(context, 'iam.permissions.sensitiveOperations', () => iam.authz.setPermissionSensitiveOperations(input.id, input.sensitiveOperations)))\n\n .route('permissions.delete')\n .permission('iam.permissions.write')\n .handle(({ input, context }) => sensitive(context, 'iam.permissions.delete', () => iam.authz.deletePermission(input.id)))\n\n .build()\n}\n\nasync function createUser(iam: IamFunctions, input: IamAdminCreateUserInput | IamInviteUserInput): Promise<HaiResult<User>> {\n const invited = !('password' in input)\n const registerResult = 'password' in input ? await iam.user.createUser(input) : await iam.user.inviteUser(input)\n if (!registerResult.success)\n return registerResult\n\n const userId = registerResult.data.user.id\n\n // 任何后续步骤失败都需要回滚刚创建的用户,以避免重复用户名/邮箱错误阅存。\n async function rollback(reason: string): Promise<void> {\n if (invited) {\n // 邀请可能已经送达,不能回滚外部已发布凭据;保留账号供管理员补齐配置。\n iamFeatureLogger.error('Invited account requires configuration repair', { userId, reason })\n return\n }\n const deleteResult = await iam.user.deleteUser(userId)\n if (!deleteResult.success)\n iamFeatureLogger.error('createUser rollback failed, orphan user may exist', { userId, reason, error: deleteResult.error })\n }\n\n if (input.roleIds !== undefined) {\n const rolesResult = await iam.authz.syncRoles(userId, input.roleIds)\n if (!rolesResult.success) {\n await rollback('syncRoles failed')\n return rolesResult\n }\n }\n\n if (input.enabled === false) {\n const updateResult = await iam.user.updateUser(userId, { enabled: false })\n if (!updateResult.success) {\n await rollback('initial disable failed')\n return updateResult\n }\n return updateResult\n }\n\n return ok(registerResult.data.user)\n}\n\nasync function updateUser(iam: IamFunctions, input: IamAdminUpdateUserInput): Promise<HaiResult<User>> {\n const { id, roleIds, ...data } = input\n const updateResult = await iam.user.updateUser(id, data)\n if (!updateResult.success)\n return updateResult\n\n if (roleIds) {\n const rolesResult = await iam.authz.syncRoles(id, roleIds)\n if (!rolesResult.success)\n return rolesResult\n }\n\n return updateResult\n}\n\n// re-export 类型以便 IDE 跳转\nexport type { TokenPair }\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/features/serv-feature-iam.ts"],"names":[],"mappings":"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","file":"iam.js","sourcesContent":["/**\n * @h-ai/serv — IAM 默认 procedures\n *\n * 基于 `@h-ai/iam` 提供开箱即用的 IAM procedures 实现:认证、用户管理、角色权限 CRUD。\n * @module features/serv-feature-iam\n */\n\nimport type {\n IamAdminCreateUserInput,\n IamAdminUpdateUserInput,\n IamCurrentUser,\n IamInviteUserInput,\n} from '@h-ai/api-contract'\nimport type { HaiResult } from '@h-ai/core'\nimport type { IamFunctions, TokenPair, User } from '@h-ai/iam'\nimport type { ServContext } from '../serv-context.js'\nimport { apiContract } from '@h-ai/api-contract'\nimport { core, err, HaiCommonError, ok } from '@h-ai/core'\nimport { servM } from '../serv-i18n.js'\nimport { implement } from '../serv-router.js'\nimport { mapHaiResult } from './serv-feature-helpers.js'\n\nconst iamContract = apiContract.iam\n\nconst iamFeatureLogger = core.logger.child({ module: 'serv', scope: 'feature-iam' })\n\n/**\n * IAM 默认 procedures 依赖。\n *\n * @example\n * ```ts\n * import { iam } from '@h-ai/iam'\n * import { createIamProcedures } from '@h-ai/serv/features/iam'\n *\n * // 宿主已初始化 IAM 及共享依赖。\n * const procedures = createIamProcedures({ iam })\n * // logout 撤销请求持有的 opaque access token;过期 access 也可撤销 refresh,\n * // 不接收 userId,不要求有效 access 的 auth guard,失败仍检查 HaiResult。\n * ```\n */\nexport interface IamProcedureDeps {\n readonly iam: IamFunctions\n}\n\n/**\n * 创建默认 IAM procedures;按操作声明认证/权限。logout 只撤销请求持有的完整 opaque token,不要求该 access 尚有效,也不能按 userId 撤销。\n *\n * @example\n * ```ts\n * import { iam } from '@h-ai/iam'\n * import { createIamProcedures } from '@h-ai/serv/features/iam'\n *\n * // 宿主已初始化 IAM 及共享依赖。\n * const procedures = createIamProcedures({ iam })\n * // logout 撤销请求持有的 opaque access token;过期 access 也可撤销 refresh,\n * // 不接收 userId,不要求有效 access 的 auth guard,失败仍检查 HaiResult。\n * ```\n */\nexport function createIamProcedures(deps: IamProcedureDeps) {\n const { iam } = deps\n\n // 权限守卫先执行;额外鉴别只绑定已授权操作,不提升原有权限。\n async function sensitive<T>(context: ServContext, operation: string, run: () => Promise<HaiResult<T>>): Promise<HaiResult<T>> {\n const policy = iam.publicConfig?.reauthentication\n if (policy?.enabled) {\n const checked = await iam.auth.checkSensitiveOperation(context.accessToken ?? '', operation, context.request.headers.get('x-hai-reauthentication') ?? undefined)\n if (!checked.success)\n return checked\n }\n return run()\n }\n\n return implement(iamContract)\n .context<ServContext>()\n\n .route('auth.reauthenticate')\n .auth()\n .handle(({ input, context }) => iam.auth.reauthenticate(context.accessToken ?? '', input.password, input.operation))\n\n .route('auth.login', ({ input, context }) => iam.auth.login(input, context))\n .route('auth.createCaptcha', ({ input }) => iam.auth.createCaptcha(input))\n .route('auth.loginWithOtp', ({ input, context }) => iam.auth.loginWithOtp(input, context))\n .route('auth.loginWithLdap', ({ input, context }) => iam.auth.loginWithLdap(input, context))\n .route('auth.publicConfig', () => iam.getPublicConfig())\n .route('auth.renewPassword', ({ input }) => iam.user.renewPassword(input))\n .route('auth.requestPasswordReset', ({ input }) => iam.user.requestPasswordReset(input.identifier, input))\n .route('auth.confirmPasswordReset', ({ input }) => iam.user.confirmPasswordReset(input.token, input.newPassword))\n\n .route('auth.logout', ({ input, context }) => {\n // 仅撤销调用方持有的完整随机令牌;不要求 access 仍有效,也不接受 userId 撤销。\n const token = input.accessToken ?? context.accessToken\n if (!token)\n return err(HaiCommonError.UNAUTHORIZED, servM('serv_errorUnauthorized', { locale: context.locale }))\n return iam.auth.logout(token)\n })\n\n .route('auth.closeSession', ({ input, context }) => {\n // 页面离开只撤销持有的会话,不清 Cookie,避免迟到响应覆盖下一文档的新登录。\n const token = input.accessToken ?? context.accessToken\n if (!token)\n return err(HaiCommonError.UNAUTHORIZED, servM('serv_errorUnauthorized', { locale: context.locale }))\n return iam.auth.logout(token)\n })\n\n .route('auth.currentUser')\n .auth()\n .handle(async ({ context }) => {\n const token = context.accessToken\n if (!token)\n return err(HaiCommonError.UNAUTHORIZED, servM('serv_errorUnauthorized', { locale: context.locale }))\n\n return mapHaiResult<User, IamCurrentUser>(\n await iam.user.getCurrentUser(token),\n user => ({\n ...user,\n roles: context.session.roles,\n permissions: context.session.permissions,\n }),\n )\n })\n\n .route('auth.refresh', async ({ input }) => {\n return mapHaiResult(await iam.session.refresh(input.refreshToken), tokens => ({ tokens }))\n })\n .route('auth.sendOtp', ({ input }) => iam.auth.sendOtp(input.identifier, input))\n .route('auth.register', ({ input, context }) => iam.auth.registerAndLogin(input, context))\n\n .route('auth.changePassword')\n .auth()\n .handle(({ input, context }) => {\n const token = context.accessToken\n if (!token)\n return err(HaiCommonError.UNAUTHORIZED, servM('serv_errorUnauthorized', { locale: context.locale }))\n return iam.user.changeCurrentUserPassword(token, input.oldPassword, input.newPassword)\n })\n\n .route('auth.updateCurrentUser')\n .auth()\n .handle(async ({ input, context }) => {\n const token = context.accessToken\n if (!token)\n return err(HaiCommonError.UNAUTHORIZED, servM('serv_errorUnauthorized', { locale: context.locale }))\n const policy = await iam.getPublicConfig()\n if (!policy.success)\n return policy\n // 标准资料入口与独立资料/头像入口共用策略;混合更新优先使用资料用途。\n const operations = [\n ...(Object.keys(input).some(key => key !== 'avatarUrl') ? ['iam.profile.update'] : []),\n ...(input.avatarUrl !== undefined ? ['iam.profile.avatar'] : []),\n ]\n const operation = operations.find(value => policy.data.reauthentication.operations.includes(value)) ?? operations[0] ?? 'iam.profile.update'\n return sensitive(context, operation, () => iam.user.updateCurrentUser(token, input))\n })\n\n .route('users.list')\n .permission('iam.users.read')\n .handle(({ input }) => iam.user.listUsers(input))\n\n .route('users.get')\n .permission('iam.users.read')\n .handle(({ input }) => iam.user.getUser(input.id, { include: ['roles'] }))\n\n .route('users.create')\n .permission('iam.users.write')\n .handle(({ input, context }) => sensitive(context, 'iam.users.create', () => createUser(iam, input)))\n\n .route('users.invite')\n .permission('iam.users.write')\n .handle(({ input, context }) => sensitive(context, 'iam.users.invite', () => createUser(iam, input)))\n\n .route('users.update')\n .permission('iam.users.write')\n .handle(({ input, context }) => sensitive(context, 'iam.users.update', () => updateUser(iam, input)))\n\n .route('users.delete')\n .permission('iam.users.write')\n .handle(({ input, context }) => {\n // 防止自删:避免管理员误删自己的账号导致授权锁死。\n if (context.session.userId === input.id)\n return err(HaiCommonError.FORBIDDEN, servM('serv_iamCannotDeleteCurrentUser', { locale: context.locale }))\n return sensitive(context, 'iam.users.delete', () => iam.user.deleteUser(input.id))\n })\n\n .route('users.resetPassword')\n .permission('iam.users.write')\n .handle(({ input, context }) => sensitive(context, 'iam.users.resetPassword', () => iam.user.adminResetPassword(input.id, input.newPassword)))\n\n .route('roles.list')\n .permission('iam.roles.read')\n .handle(() => iam.authz.getAllRoles())\n\n .route('roles.get')\n .permission('iam.roles.read')\n .handle(({ input }) => iam.authz.getRole(input.id))\n\n .route('roles.create')\n .permission('iam.roles.write')\n .handle(({ input, context }) => sensitive(context, 'iam.roles.create', () => iam.authz.createRole(input)))\n\n .route('roles.update')\n .permission('iam.roles.write')\n .handle(({ input, context }) => {\n const { id, ...data } = input\n return sensitive(context, 'iam.roles.update', () => iam.authz.updateRole(id, data))\n })\n\n .route('roles.delete')\n .permission('iam.roles.write')\n .handle(({ input, context }) => sensitive(context, 'iam.roles.delete', () => iam.authz.deleteRole(input.id)))\n\n .route('permissions.list')\n .permission('iam.permissions.read')\n .handle(({ input }) => iam.authz.getAllPermissions(input))\n\n .route('permissions.get')\n .permission('iam.permissions.read')\n .handle(({ input }) => iam.authz.getPermission(input.id))\n\n .route('permissions.create')\n .permission('iam.permissions.write')\n .handle(({ input, context }) => sensitive(context, 'iam.permissions.create', () => iam.authz.createPermission(input)))\n\n .route('permissions.setSensitiveOperations')\n .permission('iam.permissions.write')\n .handle(({ input, context }) => sensitive(context, 'iam.permissions.sensitiveOperations', () => iam.authz.setPermissionSensitiveOperations(input.id, input.sensitiveOperations)))\n\n .route('permissions.delete')\n .permission('iam.permissions.write')\n .handle(({ input, context }) => sensitive(context, 'iam.permissions.delete', () => iam.authz.deletePermission(input.id)))\n\n .build()\n}\n\nasync function createUser(iam: IamFunctions, input: IamAdminCreateUserInput | IamInviteUserInput): Promise<HaiResult<User>> {\n const invited = !('password' in input)\n const registerResult = 'password' in input ? await iam.user.createUser(input) : await iam.user.inviteUser(input)\n if (!registerResult.success)\n return registerResult\n\n const userId = registerResult.data.user.id\n\n // 任何后续步骤失败都需要回滚刚创建的用户,以避免重复用户名/邮箱错误阅存。\n async function rollback(reason: string): Promise<void> {\n if (invited) {\n // 邀请可能已经送达,不能回滚外部已发布凭据;保留账号供管理员补齐配置。\n iamFeatureLogger.error('Invited account requires configuration repair', { userId, reason })\n return\n }\n const deleteResult = await iam.user.deleteUser(userId)\n if (!deleteResult.success)\n iamFeatureLogger.error('createUser rollback failed, orphan user may exist', { userId, reason, error: deleteResult.error })\n }\n\n if (input.roleIds !== undefined) {\n const rolesResult = await iam.authz.syncRoles(userId, input.roleIds)\n if (!rolesResult.success) {\n await rollback('syncRoles failed')\n return rolesResult\n }\n }\n\n return ok(registerResult.data.user)\n}\n\nasync function updateUser(iam: IamFunctions, input: IamAdminUpdateUserInput): Promise<HaiResult<User>> {\n const { id, roleIds, ...data } = input\n const updateResult = await iam.user.updateUser(id, data)\n if (!updateResult.success)\n return updateResult\n\n if (roleIds) {\n const rolesResult = await iam.authz.syncRoles(id, roleIds)\n if (!rolesResult.success)\n return rolesResult\n }\n\n return updateResult\n}\n\n// re-export 类型以便 IDE 跳转\nexport type { TokenPair }\n"]}
|
package/dist/features/storage.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { validateInputOrFail } from '../chunk-
|
|
1
|
+
import { validateInputOrFail } from '../chunk-TWMOZPGU.js';
|
|
2
2
|
import { mapHaiResult } from '../chunk-XKCLD42I.js';
|
|
3
|
-
import { implement, servM } from '../chunk-
|
|
3
|
+
import { implement, servM } from '../chunk-I3F7RN4I.js';
|
|
4
4
|
import { apiContract, StorageDeleteSummarySchema } from '@h-ai/api-contract';
|
|
5
5
|
import { err, HaiCommonError, ok } from '@h-ai/core';
|
|
6
6
|
import { getStorageKeyIssue, StorageDeleteKeysSchema, STORAGE_KEY_MAX_BYTES } from '@h-ai/storage/schemas';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _h_ai_core from '@h-ai/core';
|
|
2
|
-
import { HaiResult, ValidationFormError } from '@h-ai/core';
|
|
2
|
+
import { HaiResult, TrustedProxies, RequestAccessConfigInput, ValidationFormError } from '@h-ai/core';
|
|
3
3
|
import { AIFunctions, AudioWsStartMessage, AudioFormat } from '@h-ai/ai';
|
|
4
4
|
import { AnyContractRouter, OpenAPI } from '@orpc/contract';
|
|
5
5
|
import { ProcedureHandler, ErrorMap, Meta, ProcedureHandlerOptions, ORPCErrorConstructorMap, Router } from '@orpc/server';
|
|
@@ -281,12 +281,14 @@ interface ServCorsRuntimeConfig {
|
|
|
281
281
|
* import type { ServHttpConfig } from '@h-ai/serv'
|
|
282
282
|
* import { serv } from '@h-ai/serv'
|
|
283
283
|
*
|
|
284
|
-
* const http: ServHttpConfig = { trustedProxies:
|
|
284
|
+
* const http: ServHttpConfig = { trustedProxies: 'auto', access: false, apiPrefix: '/api/v1', openapi: false, docs: false, health: { path: '/health' }, rpc: false }
|
|
285
285
|
* ```
|
|
286
286
|
*/
|
|
287
287
|
interface ServHttpConfig {
|
|
288
|
-
/**
|
|
289
|
-
readonly trustedProxies:
|
|
288
|
+
/** auto 仅在受管私有容器代理中采用容器网段;空数组显式忽略转发头。 */
|
|
289
|
+
readonly trustedProxies: TrustedProxies;
|
|
290
|
+
/** 每次请求的 IP/时间策略;默认 false,内联与独立文件二选一。 */
|
|
291
|
+
readonly access: RequestAccessConfigInput;
|
|
290
292
|
readonly apiPrefix: `/api/${string}`;
|
|
291
293
|
readonly openapi: false | ServOpenAPIHttpConfig;
|
|
292
294
|
readonly docs: false | ServDocsHttpConfig;
|
|
@@ -355,7 +357,8 @@ type ServTransportRuntimeConfigInput = Partial<{
|
|
|
355
357
|
* ```
|
|
356
358
|
*/
|
|
357
359
|
type ServHttpConfigInput = Partial<{
|
|
358
|
-
readonly trustedProxies:
|
|
360
|
+
readonly trustedProxies: TrustedProxies;
|
|
361
|
+
readonly access: RequestAccessConfigInput;
|
|
359
362
|
readonly apiPrefix: `/api/${string}`;
|
|
360
363
|
readonly openapi: false | Partial<ServOpenAPIHttpConfig>;
|
|
361
364
|
readonly docs: false | Partial<ServDocsHttpConfig>;
|
|
@@ -402,7 +405,48 @@ declare const ServConfigSchema: z.ZodPipe<z.ZodObject<{
|
|
|
402
405
|
port: z.ZodDefault<z.ZodNumber>;
|
|
403
406
|
}, z.core.$strip>>;
|
|
404
407
|
http: z.ZodOptional<z.ZodObject<{
|
|
405
|
-
trustedProxies: z.ZodDefault<z.ZodArray<z.
|
|
408
|
+
trustedProxies: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>]>>;
|
|
409
|
+
access: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
|
|
410
|
+
file: z.ZodString;
|
|
411
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
412
|
+
global: z.ZodOptional<z.ZodObject<{
|
|
413
|
+
allowIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
|
|
414
|
+
denyIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
|
|
415
|
+
timezone: z.ZodDefault<z.ZodString>;
|
|
416
|
+
windows: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
417
|
+
days: z.ZodArray<z.ZodNumber>;
|
|
418
|
+
start: z.ZodString;
|
|
419
|
+
end: z.ZodString;
|
|
420
|
+
}, z.core.$strict>>>;
|
|
421
|
+
}, z.core.$strict>>;
|
|
422
|
+
rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
423
|
+
allowIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
|
|
424
|
+
denyIps: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6, z.ZodCIDRv4, z.ZodCIDRv6]>>>;
|
|
425
|
+
timezone: z.ZodDefault<z.ZodString>;
|
|
426
|
+
windows: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
427
|
+
days: z.ZodArray<z.ZodNumber>;
|
|
428
|
+
start: z.ZodString;
|
|
429
|
+
end: z.ZodString;
|
|
430
|
+
}, z.core.$strict>>>;
|
|
431
|
+
id: z.ZodString;
|
|
432
|
+
paths: z.ZodArray<z.ZodString>;
|
|
433
|
+
methods: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
434
|
+
GET: "GET";
|
|
435
|
+
HEAD: "HEAD";
|
|
436
|
+
POST: "POST";
|
|
437
|
+
PUT: "PUT";
|
|
438
|
+
PATCH: "PATCH";
|
|
439
|
+
DELETE: "DELETE";
|
|
440
|
+
OPTIONS: "OPTIONS";
|
|
441
|
+
CONNECT: "CONNECT";
|
|
442
|
+
TRACE: "TRACE";
|
|
443
|
+
}>>>;
|
|
444
|
+
encryption: z.ZodOptional<z.ZodEnum<{
|
|
445
|
+
required: "required";
|
|
446
|
+
disabled: "disabled";
|
|
447
|
+
}>>;
|
|
448
|
+
}, z.core.$strict>>>;
|
|
449
|
+
}, z.core.$strict>]>>;
|
|
406
450
|
apiPrefix: z.ZodDefault<z.ZodCustom<`/api/${string}`, `/api/${string}`>>;
|
|
407
451
|
openapi: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
|
|
408
452
|
path: z.ZodDefault<z.ZodCustom<`/${string}`, `/${string}`>>;
|
|
@@ -450,7 +494,35 @@ declare const ServConfigSchema: z.ZodPipe<z.ZodObject<{
|
|
|
450
494
|
port: number;
|
|
451
495
|
} | undefined;
|
|
452
496
|
http?: {
|
|
453
|
-
trustedProxies: string[];
|
|
497
|
+
trustedProxies: string[] | "auto";
|
|
498
|
+
access: false | {
|
|
499
|
+
file: string;
|
|
500
|
+
} | {
|
|
501
|
+
rules: {
|
|
502
|
+
allowIps: string[];
|
|
503
|
+
denyIps: string[];
|
|
504
|
+
timezone: string;
|
|
505
|
+
windows: {
|
|
506
|
+
days: number[];
|
|
507
|
+
start: string;
|
|
508
|
+
end: string;
|
|
509
|
+
}[];
|
|
510
|
+
id: string;
|
|
511
|
+
paths: string[];
|
|
512
|
+
methods: ("GET" | "HEAD" | "OPTIONS" | "POST" | "PUT" | "PATCH" | "DELETE" | "CONNECT" | "TRACE")[];
|
|
513
|
+
encryption?: "required" | "disabled" | undefined;
|
|
514
|
+
}[];
|
|
515
|
+
global?: {
|
|
516
|
+
allowIps: string[];
|
|
517
|
+
denyIps: string[];
|
|
518
|
+
timezone: string;
|
|
519
|
+
windows: {
|
|
520
|
+
days: number[];
|
|
521
|
+
start: string;
|
|
522
|
+
end: string;
|
|
523
|
+
}[];
|
|
524
|
+
} | undefined;
|
|
525
|
+
};
|
|
454
526
|
apiPrefix: `/api/${string}`;
|
|
455
527
|
openapi: false | {
|
|
456
528
|
path: `/${string}`;
|
|
@@ -531,7 +603,7 @@ interface ServTransportConfig {
|
|
|
531
603
|
*
|
|
532
604
|
* - `path` 省略时默认挂到 `'*'`
|
|
533
605
|
* - 按数组顺序注册
|
|
534
|
-
* -
|
|
606
|
+
* - 普通 middleware 位于 `transport` 解密和请求访问策略之后、业务路由之前
|
|
535
607
|
*
|
|
536
608
|
* @example
|
|
537
609
|
* ```ts
|
|
@@ -539,7 +611,7 @@ interface ServTransportConfig {
|
|
|
539
611
|
* import { serv } from '@h-ai/serv'
|
|
540
612
|
*
|
|
541
613
|
* const mount: ServMiddlewareMount = { path: '/api/v1/*', middleware: serv.cors({ origin: 'https://app.example.com' }) }
|
|
542
|
-
* //
|
|
614
|
+
* // 内置 CORS 在外层补充响应头;预检仍执行访问策略。
|
|
543
615
|
* ```
|
|
544
616
|
*/
|
|
545
617
|
interface ServMiddlewareMount {
|
|
@@ -604,9 +676,9 @@ interface CreateServAppOptions<TContract extends AnyContractRouter, TProcedures
|
|
|
604
676
|
*
|
|
605
677
|
* 典型用途:请求日志、trace、指标、CORS、限流、租户头校验,以及不适合放入
|
|
606
678
|
* JSON/oRPC contract 的 WebSocket、文件或其它二进制 HTTP 端点。
|
|
607
|
-
*
|
|
608
|
-
*
|
|
609
|
-
*
|
|
679
|
+
* 普通 middleware 位于传输解密和请求访问策略之后、业务路由之前,读取的是解密正文;
|
|
680
|
+
* 提前返回仍经过传输响应加密,不能绕过访问策略。二进制端点需显式列入 transport.excludePaths。
|
|
681
|
+
* 通过 serv.cors 创建的内置 CORS 会在外层补充响应头,预检仍执行请求访问策略。
|
|
610
682
|
*/
|
|
611
683
|
readonly middlewares?: readonly ServMiddlewareMount[];
|
|
612
684
|
/**
|
|
@@ -1296,7 +1368,7 @@ declare const serv: {
|
|
|
1296
1368
|
validateInputOrFail: typeof validateInputOrFail;
|
|
1297
1369
|
WILDCARD_PERMISSION: string;
|
|
1298
1370
|
WILDCARD_ROLE: string;
|
|
1299
|
-
m: (key: "$schema" | "serv_validationFailed" | "serv_validationRequired" | "serv_validationInvalid" | "serv_validationInvalidType" | "serv_validationStringMin" | "serv_validationStringMax" | "serv_validationNumberMin" | "serv_validationNumberMax" | "serv_validationArrayMin" | "serv_validationArrayMax" | "serv_validationTooSmall" | "serv_validationTooBig" | "serv_validationEmail" | "serv_validationUrl" | "serv_validationUuid" | "serv_validationEnum" | "serv_errorUnauthorized" | "serv_errorForbidden" | "serv_errorInternal" | "serv_storageKeyRequired" | "serv_storageKeyTooLong" | "serv_storageKeyIllegalChars" | "serv_storageKeyDotSegments" | "serv_iamCannotDeleteCurrentUser" | "serv_transportInvalidPayload" | "serv_transportUnknownClient" | "serv_transportClientIdRequired" | "serv_transportClientKeyNotFound" | "serv_transportDecryptFailed" | "serv_transportEncryptFailed" | "serv_transportKeyExchangeFailed" | "serv_transportBusy" | "serv_feedbackUnavailable", options?: _h_ai_core.MessageOptions) => string;
|
|
1371
|
+
m: (key: "serv_transportPlaintextRequired" | "$schema" | "serv_validationFailed" | "serv_validationRequired" | "serv_validationInvalid" | "serv_validationInvalidType" | "serv_validationUnexpectedFields" | "serv_validationStringMin" | "serv_validationStringMax" | "serv_validationNumberMin" | "serv_validationNumberMax" | "serv_validationArrayMin" | "serv_validationArrayMax" | "serv_validationTooSmall" | "serv_validationTooBig" | "serv_validationEmail" | "serv_validationUrl" | "serv_validationUuid" | "serv_validationEnum" | "serv_errorUnauthorized" | "serv_errorForbidden" | "serv_errorInternal" | "serv_storageKeyRequired" | "serv_storageKeyTooLong" | "serv_storageKeyIllegalChars" | "serv_storageKeyDotSegments" | "serv_iamCannotDeleteCurrentUser" | "serv_transportInvalidPayload" | "serv_transportUnknownClient" | "serv_transportClientIdRequired" | "serv_transportClientKeyNotFound" | "serv_transportDecryptFailed" | "serv_transportEncryptFailed" | "serv_transportKeyExchangeFailed" | "serv_transportBusy" | "serv_feedbackUnavailable", options?: _h_ai_core.MessageOptions) => string;
|
|
1300
1372
|
};
|
|
1301
1373
|
|
|
1302
1374
|
export { type AudioTicketGrant, type AudioTicketVerification, type AuthorizedAudioRequest, type CreateServAppOptions, CreateServContext, type GenerateOpenAPISpecOptions, RefreshCookieConfig, type ServAudioConfig, type ServConfig, type ServConfigInput, ServConfigSchema, ServContext, type ServCorsConfig, type ServCorsRuntimeConfig, type ServCorsRuntimeConfigInput, type ServDocsHttpConfig, type ServFetchHandler, type ServHealthHttpConfig, type ServHttpApp, type ServHttpConfig, type ServHttpConfigInput, ServIam, type ServListenOptions, type ServMiddleware, type ServMiddlewareFactory, type ServMiddlewareMount, type ServNodeServer, type ServOpenAPIHttpConfig, type ServProcedureHandler, type ServProcedureOptions, ServRequestMetadata, type ServRpcHttpConfig, type ServRuntimeSecurityPolicy, type ServRuntimeSecurityPolicyInput, type ServServerConfig, type ServServerConfigInput, ServSession, type ServStorageAssetsConfig, type ServTransportConfig, type ServTransportRuntimeConfig, type ServTransportRuntimeConfigInput, type ServValidationFailureBody, serv };
|