@appforge-ci/core 0.2.3 → 0.3.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/agent-readiness.d.ts +232 -1
- package/dist/agent-readiness.d.ts.map +1 -1
- package/dist/agent-readiness.js +294 -1
- package/dist/agent-readiness.js.map +1 -1
- package/dist/agent-readiness.test.js +253 -19
- package/dist/agent-readiness.test.js.map +1 -1
- package/dist/api-client.d.ts +42 -3
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +27 -0
- package/dist/api-client.js.map +1 -1
- package/dist/api-client.test.js +22 -0
- package/dist/api-client.test.js.map +1 -1
- package/dist/attestation.d.ts +265 -0
- package/dist/attestation.d.ts.map +1 -0
- package/dist/attestation.js +327 -0
- package/dist/attestation.js.map +1 -0
- package/dist/attestation.test.d.ts +2 -0
- package/dist/attestation.test.d.ts.map +1 -0
- package/dist/attestation.test.js +218 -0
- package/dist/attestation.test.js.map +1 -0
- package/dist/build-vpn.d.ts +10 -0
- package/dist/build-vpn.d.ts.map +1 -0
- package/dist/build-vpn.js +23 -0
- package/dist/build-vpn.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/schemas.d.ts +342 -7
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +92 -2
- package/dist/schemas.js.map +1 -1
- package/dist/types.d.ts +149 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vpn-egress-presets.d.ts +142 -0
- package/dist/vpn-egress-presets.d.ts.map +1 -0
- package/dist/vpn-egress-presets.js +318 -0
- package/dist/vpn-egress-presets.js.map +1 -0
- package/dist/vpn-egress-presets.test.d.ts +2 -0
- package/dist/vpn-egress-presets.test.d.ts.map +1 -0
- package/dist/vpn-egress-presets.test.js +210 -0
- package/dist/vpn-egress-presets.test.js.map +1 -0
- package/dist/vpn-egress.d.ts +57 -0
- package/dist/vpn-egress.d.ts.map +1 -0
- package/dist/vpn-egress.js +126 -0
- package/dist/vpn-egress.js.map +1 -0
- package/dist/vpn-egress.test.d.ts +2 -0
- package/dist/vpn-egress.test.d.ts.map +1 -0
- package/dist/vpn-egress.test.js +133 -0
- package/dist/vpn-egress.test.js.map +1 -0
- package/dist/vpn-ssh.d.ts +45 -0
- package/dist/vpn-ssh.d.ts.map +1 -0
- package/dist/vpn-ssh.js +108 -0
- package/dist/vpn-ssh.js.map +1 -0
- package/dist/vpn-ssh.test.d.ts +2 -0
- package/dist/vpn-ssh.test.d.ts.map +1 -0
- package/dist/vpn-ssh.test.js +75 -0
- package/dist/vpn-ssh.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-vpn.js","sourceRoot":"","sources":["../src/build-vpn.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAA+B;IAC9D,IAAI,CAAC,GAAG;QAAE,OAAO,0BAA0B,CAAC;IAC5C,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,IAAI,QAAQ,CAAC;IACxC,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,IAAI,GAAG,CAAC,OAAO,KAAK,WAAW;YAAE,OAAO,qBAAqB,IAAI,cAAc,CAAC;QAChF,IAAI,GAAG,CAAC,OAAO,KAAK,QAAQ;YAAE,OAAO,sBAAsB,GAAG,CAAC,MAAM,IAAI,gCAAgC,EAAE,CAAC;QAC5G,OAAO,kBAAkB,IAAI,oCAAoC,CAAC;IACpE,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,gEAAgE,CAAC;IACvG,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,5 +6,10 @@ export * from "./ota-rollout.js";
|
|
|
6
6
|
export * from "./ota-bundle-hash.js";
|
|
7
7
|
export * from "./ota-artifact.js";
|
|
8
8
|
export * from "./vpn-network.js";
|
|
9
|
+
export * from "./vpn-egress.js";
|
|
10
|
+
export * from "./vpn-ssh.js";
|
|
11
|
+
export * from "./vpn-egress-presets.js";
|
|
9
12
|
export * from "./artifact-upload.js";
|
|
13
|
+
export * from "./build-vpn.js";
|
|
14
|
+
export * from "./attestation.js";
|
|
10
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,5 +6,10 @@ export * from "./ota-rollout.js";
|
|
|
6
6
|
export * from "./ota-bundle-hash.js";
|
|
7
7
|
export * from "./ota-artifact.js";
|
|
8
8
|
export * from "./vpn-network.js";
|
|
9
|
+
export * from "./vpn-egress.js";
|
|
10
|
+
export * from "./vpn-ssh.js";
|
|
11
|
+
export * from "./vpn-egress-presets.js";
|
|
9
12
|
export * from "./artifact-upload.js";
|
|
13
|
+
export * from "./build-vpn.js";
|
|
14
|
+
export * from "./attestation.js";
|
|
10
15
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC"}
|
package/dist/schemas.d.ts
CHANGED
|
@@ -492,14 +492,14 @@ export declare const updateAppSchema: z.ZodObject<{
|
|
|
492
492
|
useVpn: z.ZodOptional<z.ZodBoolean>;
|
|
493
493
|
}, "strip", z.ZodTypeAny, {
|
|
494
494
|
name?: string | undefined;
|
|
495
|
+
useVpn?: boolean | undefined;
|
|
495
496
|
repoUrl?: string | undefined;
|
|
496
497
|
defaultBranch?: string | undefined;
|
|
497
|
-
useVpn?: boolean | undefined;
|
|
498
498
|
}, {
|
|
499
499
|
name?: string | undefined;
|
|
500
|
+
useVpn?: boolean | undefined;
|
|
500
501
|
repoUrl?: string | undefined;
|
|
501
502
|
defaultBranch?: string | undefined;
|
|
502
|
-
useVpn?: boolean | undefined;
|
|
503
503
|
}>;
|
|
504
504
|
export declare const updateOrgSchema: z.ZodObject<{
|
|
505
505
|
name: z.ZodOptional<z.ZodString>;
|
|
@@ -629,6 +629,20 @@ export declare const agentHeartbeatSchema: z.ZodObject<{
|
|
|
629
629
|
* predates the VPN feature omits it and stays `vpnCapable = 0`, so it
|
|
630
630
|
* is never offered a VPN build. */
|
|
631
631
|
vpnCapable: z.ZodOptional<z.ZodBoolean>;
|
|
632
|
+
/** VPN features this agent can enforce (migrations/0043) — ids matching
|
|
633
|
+
* `VPN_FEATURE_ID_PATTERN`, at most `MAX_VPN_FEATURES`. Like `vpnCapable`
|
|
634
|
+
* the stored value is derived from THIS heartbeat alone: omitting it (an
|
|
635
|
+
* older agent) means "no features", never "keep the last value". A
|
|
636
|
+
* malformed list is rejected (400) rather than half-trusted. */
|
|
637
|
+
vpnFeatures: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
638
|
+
/** Build-isolation level this agent enforces (migrations/0043). Same
|
|
639
|
+
* omit-means-default (`none`) rule as `vpnFeatures`. */
|
|
640
|
+
enforcementLevel: z.ZodOptional<z.ZodEnum<["none", "sandbox", "sandbox_uid"]>>;
|
|
641
|
+
/** Whether a GitHub Actions self-hosted runner shares this machine
|
|
642
|
+
* (migrations/0047). Like `vpnFeatures`, stored from THIS heartbeat alone:
|
|
643
|
+
* omitted (an older agent, or a check that failed) means "unknown", never
|
|
644
|
+
* "keep the last value", and unknown refuses a dedicated host. */
|
|
645
|
+
coHostedRunner: z.ZodOptional<z.ZodBoolean>;
|
|
632
646
|
}, "strip", z.ZodTypeAny, {
|
|
633
647
|
status: "online" | "draining" | "building";
|
|
634
648
|
xcodeVersion: string | null;
|
|
@@ -642,6 +656,9 @@ export declare const agentHeartbeatSchema: z.ZodObject<{
|
|
|
642
656
|
agentVersion?: string | null | undefined;
|
|
643
657
|
screenSharingEnabled?: boolean | null | undefined;
|
|
644
658
|
vpnCapable?: boolean | undefined;
|
|
659
|
+
vpnFeatures?: string[] | undefined;
|
|
660
|
+
enforcementLevel?: "none" | "sandbox" | "sandbox_uid" | undefined;
|
|
661
|
+
coHostedRunner?: boolean | undefined;
|
|
645
662
|
tailscaleHostname?: string | null | undefined;
|
|
646
663
|
currentBuildId?: string | null | undefined;
|
|
647
664
|
activeBuildIds?: string[] | undefined;
|
|
@@ -659,6 +676,9 @@ export declare const agentHeartbeatSchema: z.ZodObject<{
|
|
|
659
676
|
agentVersion?: string | null | undefined;
|
|
660
677
|
screenSharingEnabled?: boolean | null | undefined;
|
|
661
678
|
vpnCapable?: boolean | undefined;
|
|
679
|
+
vpnFeatures?: string[] | undefined;
|
|
680
|
+
enforcementLevel?: "none" | "sandbox" | "sandbox_uid" | undefined;
|
|
681
|
+
coHostedRunner?: boolean | undefined;
|
|
662
682
|
tailscaleHostname?: string | null | undefined;
|
|
663
683
|
currentBuildId?: string | null | undefined;
|
|
664
684
|
activeBuildIds?: string[] | undefined;
|
|
@@ -668,11 +688,11 @@ export declare const appendLogSchema: z.ZodObject<{
|
|
|
668
688
|
chunk: z.ZodString;
|
|
669
689
|
seq: z.ZodNumber;
|
|
670
690
|
}, "strip", z.ZodTypeAny, {
|
|
671
|
-
chunk: string;
|
|
672
691
|
seq: number;
|
|
673
|
-
}, {
|
|
674
692
|
chunk: string;
|
|
693
|
+
}, {
|
|
675
694
|
seq: number;
|
|
695
|
+
chunk: string;
|
|
676
696
|
}>;
|
|
677
697
|
export declare const completeBuildSchema: z.ZodObject<{
|
|
678
698
|
status: z.ZodEnum<["succeeded", "failed"]>;
|
|
@@ -737,8 +757,8 @@ export declare const promoteOtaReleaseSchema: z.ZodObject<{
|
|
|
737
757
|
rollout: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
738
758
|
}, "strip", z.ZodTypeAny, {
|
|
739
759
|
channel: string;
|
|
740
|
-
mandatory: boolean;
|
|
741
760
|
buildId: string;
|
|
761
|
+
mandatory: boolean;
|
|
742
762
|
rollout: number;
|
|
743
763
|
}, {
|
|
744
764
|
buildId: string;
|
|
@@ -785,6 +805,29 @@ export declare const setAgentVpnApprovedSchema: z.ZodObject<{
|
|
|
785
805
|
}, {
|
|
786
806
|
approved: boolean;
|
|
787
807
|
}>;
|
|
808
|
+
/** `PATCH /orgs/:orgId/agents/:agentId/dedicated` (apps/admin-api) — the
|
|
809
|
+
* only way `Agent.dedicatedOrgId` ever changes (migrations/0043). An
|
|
810
|
+
* operator taint, deliberately not in agentHeartbeatSchema/agentEnrollSchema:
|
|
811
|
+
* an agent must never be able to widen or lift its own restriction. `null`
|
|
812
|
+
* clears it (the Mac goes back to being shared). */
|
|
813
|
+
export declare const setAgentDedicatedOrgSchema: z.ZodObject<{
|
|
814
|
+
dedicatedOrgId: z.ZodNullable<z.ZodString>;
|
|
815
|
+
}, "strip", z.ZodTypeAny, {
|
|
816
|
+
dedicatedOrgId: string | null;
|
|
817
|
+
}, {
|
|
818
|
+
dedicatedOrgId: string | null;
|
|
819
|
+
}>;
|
|
820
|
+
/** `PATCH /orgs/:orgId/vpn-hosts/:tunnelOrgId/policy` (apps/admin-api, platform
|
|
821
|
+
* admins only) — the only way `VpnTunnel.hostPolicy` ever changes
|
|
822
|
+
* (migrations/0047). Deliberately not in `updateVpnTunnelSchema`: an org
|
|
823
|
+
* admin must not be able to loosen the placement the operator set. */
|
|
824
|
+
export declare const setVpnHostPolicySchema: z.ZodObject<{
|
|
825
|
+
hostPolicy: z.ZodEnum<["shared", "pinned", "dedicated"]>;
|
|
826
|
+
}, "strip", z.ZodTypeAny, {
|
|
827
|
+
hostPolicy: "shared" | "pinned" | "dedicated";
|
|
828
|
+
}, {
|
|
829
|
+
hostPolicy: "shared" | "pinned" | "dedicated";
|
|
830
|
+
}>;
|
|
788
831
|
/** `PATCH /orgs/:orgId/agents/:agentId/device-stream-hostname` (apps/
|
|
789
832
|
* admin-api)'s request body — `hostname: null` clears it, going back
|
|
790
833
|
* to the global DEVICE_STREAM_WS_URL fallback (see migrations/0034's
|
|
@@ -812,7 +855,159 @@ export declare const startVncSessionSchema: z.ZodObject<{
|
|
|
812
855
|
}, {
|
|
813
856
|
mode?: "view" | "control" | undefined;
|
|
814
857
|
}>;
|
|
815
|
-
|
|
858
|
+
/**
|
|
859
|
+
* The shape-only form of the create/update bodies, WITHOUT the egress rules. The
|
|
860
|
+
* API route parses with these and then runs `resolveEgressChange`, which applies
|
|
861
|
+
* the same `validateEgressSettings` but answers with a structured 400 listing
|
|
862
|
+
* every problem (`errors`) rather than a generic schema error. Anything else
|
|
863
|
+
* should use `createVpnTunnelSchema` / `updateVpnTunnelSchema` below.
|
|
864
|
+
*/
|
|
865
|
+
export declare const createVpnTunnelBodySchema: z.ZodObject<{
|
|
866
|
+
/** `regulated` needs `strictEgress`, and the operator's REGULATED_VPN_ENABLED flag. */
|
|
867
|
+
complianceMode: z.ZodOptional<z.ZodEnum<["standard", "regulated"]>>;
|
|
868
|
+
strictEgress: z.ZodOptional<z.ZodBoolean>;
|
|
869
|
+
/** Preset ids; replaces the list. */
|
|
870
|
+
egressPresets: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
871
|
+
/** Custom hosts (exact or `*.suffix`, port 443 unless `ports` says otherwise); replaces the list. */
|
|
872
|
+
egressAllow: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
873
|
+
host: z.ZodString;
|
|
874
|
+
ports: z.ZodOptional<z.ZodArray<z.ZodNumber, "many">>;
|
|
875
|
+
}, "strip", z.ZodTypeAny, {
|
|
876
|
+
host: string;
|
|
877
|
+
ports?: number[] | undefined;
|
|
878
|
+
}, {
|
|
879
|
+
host: string;
|
|
880
|
+
ports?: number[] | undefined;
|
|
881
|
+
}>, "many">>;
|
|
882
|
+
name: z.ZodString;
|
|
883
|
+
gatewayEndpoint: z.ZodString;
|
|
884
|
+
gatewayPublicKey: z.ZodString;
|
|
885
|
+
lanCidrs: z.ZodArray<z.ZodString, "many">;
|
|
886
|
+
dnsServer: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
887
|
+
allowedDomains: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
888
|
+
/** Omit to have the server allocate a free /30. Supply it only when a
|
|
889
|
+
* customer network already routes the allocated range. */
|
|
890
|
+
tunnelCidr: z.ZodOptional<z.ZodString>;
|
|
891
|
+
/** Lab mode — allow a private (RFC1918/CGNAT) gateway endpoint. Setting it
|
|
892
|
+
* `true` is platform-admin only (enforced by the route, not here). */
|
|
893
|
+
allowPrivateEndpoint: z.ZodOptional<z.ZodBoolean>;
|
|
894
|
+
}, "strip", z.ZodTypeAny, {
|
|
895
|
+
name: string;
|
|
896
|
+
gatewayEndpoint: string;
|
|
897
|
+
gatewayPublicKey: string;
|
|
898
|
+
lanCidrs: string[];
|
|
899
|
+
egressAllow?: {
|
|
900
|
+
host: string;
|
|
901
|
+
ports?: number[] | undefined;
|
|
902
|
+
}[] | undefined;
|
|
903
|
+
egressPresets?: string[] | undefined;
|
|
904
|
+
dnsServer?: string | null | undefined;
|
|
905
|
+
allowedDomains?: string[] | undefined;
|
|
906
|
+
tunnelCidr?: string | undefined;
|
|
907
|
+
allowPrivateEndpoint?: boolean | undefined;
|
|
908
|
+
complianceMode?: "standard" | "regulated" | undefined;
|
|
909
|
+
strictEgress?: boolean | undefined;
|
|
910
|
+
}, {
|
|
911
|
+
name: string;
|
|
912
|
+
gatewayEndpoint: string;
|
|
913
|
+
gatewayPublicKey: string;
|
|
914
|
+
lanCidrs: string[];
|
|
915
|
+
egressAllow?: {
|
|
916
|
+
host: string;
|
|
917
|
+
ports?: number[] | undefined;
|
|
918
|
+
}[] | undefined;
|
|
919
|
+
egressPresets?: string[] | undefined;
|
|
920
|
+
dnsServer?: string | null | undefined;
|
|
921
|
+
allowedDomains?: string[] | undefined;
|
|
922
|
+
tunnelCidr?: string | undefined;
|
|
923
|
+
allowPrivateEndpoint?: boolean | undefined;
|
|
924
|
+
complianceMode?: "standard" | "regulated" | undefined;
|
|
925
|
+
strictEgress?: boolean | undefined;
|
|
926
|
+
}>;
|
|
927
|
+
export declare const updateVpnTunnelBodySchema: z.ZodObject<{
|
|
928
|
+
/** `regulated` needs `strictEgress`, and the operator's REGULATED_VPN_ENABLED flag. */
|
|
929
|
+
complianceMode: z.ZodOptional<z.ZodEnum<["standard", "regulated"]>>;
|
|
930
|
+
strictEgress: z.ZodOptional<z.ZodBoolean>;
|
|
931
|
+
/** Preset ids; replaces the list. */
|
|
932
|
+
egressPresets: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
933
|
+
/** Custom hosts (exact or `*.suffix`, port 443 unless `ports` says otherwise); replaces the list. */
|
|
934
|
+
egressAllow: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
935
|
+
host: z.ZodString;
|
|
936
|
+
ports: z.ZodOptional<z.ZodArray<z.ZodNumber, "many">>;
|
|
937
|
+
}, "strip", z.ZodTypeAny, {
|
|
938
|
+
host: string;
|
|
939
|
+
ports?: number[] | undefined;
|
|
940
|
+
}, {
|
|
941
|
+
host: string;
|
|
942
|
+
ports?: number[] | undefined;
|
|
943
|
+
}>, "many">>;
|
|
944
|
+
name: z.ZodOptional<z.ZodString>;
|
|
945
|
+
gatewayEndpoint: z.ZodOptional<z.ZodString>;
|
|
946
|
+
gatewayPublicKey: z.ZodOptional<z.ZodString>;
|
|
947
|
+
lanCidrs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
948
|
+
/** Explicit `null` clears it; omitted leaves it unchanged. */
|
|
949
|
+
dnsServer: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
950
|
+
allowedDomains: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
951
|
+
tunnelCidr: z.ZodOptional<z.ZodString>;
|
|
952
|
+
/** Lab mode. `true` is platform-admin only; omitted leaves it unchanged. */
|
|
953
|
+
allowPrivateEndpoint: z.ZodOptional<z.ZodBoolean>;
|
|
954
|
+
/** `false` disables the tunnel (builds that need it then fail fast
|
|
955
|
+
* instead of queueing); `true` re-enables it, back to `pending` until
|
|
956
|
+
* the next handshake proves it works. */
|
|
957
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
958
|
+
}, "strip", z.ZodTypeAny, {
|
|
959
|
+
name?: string | undefined;
|
|
960
|
+
egressAllow?: {
|
|
961
|
+
host: string;
|
|
962
|
+
ports?: number[] | undefined;
|
|
963
|
+
}[] | undefined;
|
|
964
|
+
egressPresets?: string[] | undefined;
|
|
965
|
+
enabled?: boolean | undefined;
|
|
966
|
+
gatewayEndpoint?: string | undefined;
|
|
967
|
+
gatewayPublicKey?: string | undefined;
|
|
968
|
+
lanCidrs?: string[] | undefined;
|
|
969
|
+
dnsServer?: string | null | undefined;
|
|
970
|
+
allowedDomains?: string[] | undefined;
|
|
971
|
+
tunnelCidr?: string | undefined;
|
|
972
|
+
allowPrivateEndpoint?: boolean | undefined;
|
|
973
|
+
complianceMode?: "standard" | "regulated" | undefined;
|
|
974
|
+
strictEgress?: boolean | undefined;
|
|
975
|
+
}, {
|
|
976
|
+
name?: string | undefined;
|
|
977
|
+
egressAllow?: {
|
|
978
|
+
host: string;
|
|
979
|
+
ports?: number[] | undefined;
|
|
980
|
+
}[] | undefined;
|
|
981
|
+
egressPresets?: string[] | undefined;
|
|
982
|
+
enabled?: boolean | undefined;
|
|
983
|
+
gatewayEndpoint?: string | undefined;
|
|
984
|
+
gatewayPublicKey?: string | undefined;
|
|
985
|
+
lanCidrs?: string[] | undefined;
|
|
986
|
+
dnsServer?: string | null | undefined;
|
|
987
|
+
allowedDomains?: string[] | undefined;
|
|
988
|
+
tunnelCidr?: string | undefined;
|
|
989
|
+
allowPrivateEndpoint?: boolean | undefined;
|
|
990
|
+
complianceMode?: "standard" | "regulated" | undefined;
|
|
991
|
+
strictEgress?: boolean | undefined;
|
|
992
|
+
}>;
|
|
993
|
+
/** The create body, with the egress rules (bare `*`, IP literals, unknown presets, merged port limit) enforced too. */
|
|
994
|
+
export declare const createVpnTunnelSchema: z.ZodEffects<z.ZodObject<{
|
|
995
|
+
/** `regulated` needs `strictEgress`, and the operator's REGULATED_VPN_ENABLED flag. */
|
|
996
|
+
complianceMode: z.ZodOptional<z.ZodEnum<["standard", "regulated"]>>;
|
|
997
|
+
strictEgress: z.ZodOptional<z.ZodBoolean>;
|
|
998
|
+
/** Preset ids; replaces the list. */
|
|
999
|
+
egressPresets: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
1000
|
+
/** Custom hosts (exact or `*.suffix`, port 443 unless `ports` says otherwise); replaces the list. */
|
|
1001
|
+
egressAllow: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1002
|
+
host: z.ZodString;
|
|
1003
|
+
ports: z.ZodOptional<z.ZodArray<z.ZodNumber, "many">>;
|
|
1004
|
+
}, "strip", z.ZodTypeAny, {
|
|
1005
|
+
host: string;
|
|
1006
|
+
ports?: number[] | undefined;
|
|
1007
|
+
}, {
|
|
1008
|
+
host: string;
|
|
1009
|
+
ports?: number[] | undefined;
|
|
1010
|
+
}>, "many">>;
|
|
816
1011
|
name: z.ZodString;
|
|
817
1012
|
gatewayEndpoint: z.ZodString;
|
|
818
1013
|
gatewayPublicKey: z.ZodString;
|
|
@@ -830,21 +1025,84 @@ export declare const createVpnTunnelSchema: z.ZodObject<{
|
|
|
830
1025
|
gatewayEndpoint: string;
|
|
831
1026
|
gatewayPublicKey: string;
|
|
832
1027
|
lanCidrs: string[];
|
|
1028
|
+
egressAllow?: {
|
|
1029
|
+
host: string;
|
|
1030
|
+
ports?: number[] | undefined;
|
|
1031
|
+
}[] | undefined;
|
|
1032
|
+
egressPresets?: string[] | undefined;
|
|
833
1033
|
dnsServer?: string | null | undefined;
|
|
834
1034
|
allowedDomains?: string[] | undefined;
|
|
835
1035
|
tunnelCidr?: string | undefined;
|
|
836
1036
|
allowPrivateEndpoint?: boolean | undefined;
|
|
1037
|
+
complianceMode?: "standard" | "regulated" | undefined;
|
|
1038
|
+
strictEgress?: boolean | undefined;
|
|
837
1039
|
}, {
|
|
838
1040
|
name: string;
|
|
839
1041
|
gatewayEndpoint: string;
|
|
840
1042
|
gatewayPublicKey: string;
|
|
841
1043
|
lanCidrs: string[];
|
|
1044
|
+
egressAllow?: {
|
|
1045
|
+
host: string;
|
|
1046
|
+
ports?: number[] | undefined;
|
|
1047
|
+
}[] | undefined;
|
|
1048
|
+
egressPresets?: string[] | undefined;
|
|
842
1049
|
dnsServer?: string | null | undefined;
|
|
843
1050
|
allowedDomains?: string[] | undefined;
|
|
844
1051
|
tunnelCidr?: string | undefined;
|
|
845
1052
|
allowPrivateEndpoint?: boolean | undefined;
|
|
1053
|
+
complianceMode?: "standard" | "regulated" | undefined;
|
|
1054
|
+
strictEgress?: boolean | undefined;
|
|
1055
|
+
}>, {
|
|
1056
|
+
name: string;
|
|
1057
|
+
gatewayEndpoint: string;
|
|
1058
|
+
gatewayPublicKey: string;
|
|
1059
|
+
lanCidrs: string[];
|
|
1060
|
+
egressAllow?: {
|
|
1061
|
+
host: string;
|
|
1062
|
+
ports?: number[] | undefined;
|
|
1063
|
+
}[] | undefined;
|
|
1064
|
+
egressPresets?: string[] | undefined;
|
|
1065
|
+
dnsServer?: string | null | undefined;
|
|
1066
|
+
allowedDomains?: string[] | undefined;
|
|
1067
|
+
tunnelCidr?: string | undefined;
|
|
1068
|
+
allowPrivateEndpoint?: boolean | undefined;
|
|
1069
|
+
complianceMode?: "standard" | "regulated" | undefined;
|
|
1070
|
+
strictEgress?: boolean | undefined;
|
|
1071
|
+
}, {
|
|
1072
|
+
name: string;
|
|
1073
|
+
gatewayEndpoint: string;
|
|
1074
|
+
gatewayPublicKey: string;
|
|
1075
|
+
lanCidrs: string[];
|
|
1076
|
+
egressAllow?: {
|
|
1077
|
+
host: string;
|
|
1078
|
+
ports?: number[] | undefined;
|
|
1079
|
+
}[] | undefined;
|
|
1080
|
+
egressPresets?: string[] | undefined;
|
|
1081
|
+
dnsServer?: string | null | undefined;
|
|
1082
|
+
allowedDomains?: string[] | undefined;
|
|
1083
|
+
tunnelCidr?: string | undefined;
|
|
1084
|
+
allowPrivateEndpoint?: boolean | undefined;
|
|
1085
|
+
complianceMode?: "standard" | "regulated" | undefined;
|
|
1086
|
+
strictEgress?: boolean | undefined;
|
|
846
1087
|
}>;
|
|
847
|
-
|
|
1088
|
+
/** The update body, with the egress rules enforced too. */
|
|
1089
|
+
export declare const updateVpnTunnelSchema: z.ZodEffects<z.ZodObject<{
|
|
1090
|
+
/** `regulated` needs `strictEgress`, and the operator's REGULATED_VPN_ENABLED flag. */
|
|
1091
|
+
complianceMode: z.ZodOptional<z.ZodEnum<["standard", "regulated"]>>;
|
|
1092
|
+
strictEgress: z.ZodOptional<z.ZodBoolean>;
|
|
1093
|
+
/** Preset ids; replaces the list. */
|
|
1094
|
+
egressPresets: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
1095
|
+
/** Custom hosts (exact or `*.suffix`, port 443 unless `ports` says otherwise); replaces the list. */
|
|
1096
|
+
egressAllow: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1097
|
+
host: z.ZodString;
|
|
1098
|
+
ports: z.ZodOptional<z.ZodArray<z.ZodNumber, "many">>;
|
|
1099
|
+
}, "strip", z.ZodTypeAny, {
|
|
1100
|
+
host: string;
|
|
1101
|
+
ports?: number[] | undefined;
|
|
1102
|
+
}, {
|
|
1103
|
+
host: string;
|
|
1104
|
+
ports?: number[] | undefined;
|
|
1105
|
+
}>, "many">>;
|
|
848
1106
|
name: z.ZodOptional<z.ZodString>;
|
|
849
1107
|
gatewayEndpoint: z.ZodOptional<z.ZodString>;
|
|
850
1108
|
gatewayPublicKey: z.ZodOptional<z.ZodString>;
|
|
@@ -861,6 +1119,11 @@ export declare const updateVpnTunnelSchema: z.ZodObject<{
|
|
|
861
1119
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
862
1120
|
}, "strip", z.ZodTypeAny, {
|
|
863
1121
|
name?: string | undefined;
|
|
1122
|
+
egressAllow?: {
|
|
1123
|
+
host: string;
|
|
1124
|
+
ports?: number[] | undefined;
|
|
1125
|
+
}[] | undefined;
|
|
1126
|
+
egressPresets?: string[] | undefined;
|
|
864
1127
|
enabled?: boolean | undefined;
|
|
865
1128
|
gatewayEndpoint?: string | undefined;
|
|
866
1129
|
gatewayPublicKey?: string | undefined;
|
|
@@ -869,8 +1132,15 @@ export declare const updateVpnTunnelSchema: z.ZodObject<{
|
|
|
869
1132
|
allowedDomains?: string[] | undefined;
|
|
870
1133
|
tunnelCidr?: string | undefined;
|
|
871
1134
|
allowPrivateEndpoint?: boolean | undefined;
|
|
1135
|
+
complianceMode?: "standard" | "regulated" | undefined;
|
|
1136
|
+
strictEgress?: boolean | undefined;
|
|
872
1137
|
}, {
|
|
873
1138
|
name?: string | undefined;
|
|
1139
|
+
egressAllow?: {
|
|
1140
|
+
host: string;
|
|
1141
|
+
ports?: number[] | undefined;
|
|
1142
|
+
}[] | undefined;
|
|
1143
|
+
egressPresets?: string[] | undefined;
|
|
874
1144
|
enabled?: boolean | undefined;
|
|
875
1145
|
gatewayEndpoint?: string | undefined;
|
|
876
1146
|
gatewayPublicKey?: string | undefined;
|
|
@@ -879,6 +1149,71 @@ export declare const updateVpnTunnelSchema: z.ZodObject<{
|
|
|
879
1149
|
allowedDomains?: string[] | undefined;
|
|
880
1150
|
tunnelCidr?: string | undefined;
|
|
881
1151
|
allowPrivateEndpoint?: boolean | undefined;
|
|
1152
|
+
complianceMode?: "standard" | "regulated" | undefined;
|
|
1153
|
+
strictEgress?: boolean | undefined;
|
|
1154
|
+
}>, {
|
|
1155
|
+
name?: string | undefined;
|
|
1156
|
+
egressAllow?: {
|
|
1157
|
+
host: string;
|
|
1158
|
+
ports?: number[] | undefined;
|
|
1159
|
+
}[] | undefined;
|
|
1160
|
+
egressPresets?: string[] | undefined;
|
|
1161
|
+
enabled?: boolean | undefined;
|
|
1162
|
+
gatewayEndpoint?: string | undefined;
|
|
1163
|
+
gatewayPublicKey?: string | undefined;
|
|
1164
|
+
lanCidrs?: string[] | undefined;
|
|
1165
|
+
dnsServer?: string | null | undefined;
|
|
1166
|
+
allowedDomains?: string[] | undefined;
|
|
1167
|
+
tunnelCidr?: string | undefined;
|
|
1168
|
+
allowPrivateEndpoint?: boolean | undefined;
|
|
1169
|
+
complianceMode?: "standard" | "regulated" | undefined;
|
|
1170
|
+
strictEgress?: boolean | undefined;
|
|
1171
|
+
}, {
|
|
1172
|
+
name?: string | undefined;
|
|
1173
|
+
egressAllow?: {
|
|
1174
|
+
host: string;
|
|
1175
|
+
ports?: number[] | undefined;
|
|
1176
|
+
}[] | undefined;
|
|
1177
|
+
egressPresets?: string[] | undefined;
|
|
1178
|
+
enabled?: boolean | undefined;
|
|
1179
|
+
gatewayEndpoint?: string | undefined;
|
|
1180
|
+
gatewayPublicKey?: string | undefined;
|
|
1181
|
+
lanCidrs?: string[] | undefined;
|
|
1182
|
+
dnsServer?: string | null | undefined;
|
|
1183
|
+
allowedDomains?: string[] | undefined;
|
|
1184
|
+
tunnelCidr?: string | undefined;
|
|
1185
|
+
allowPrivateEndpoint?: boolean | undefined;
|
|
1186
|
+
complianceMode?: "standard" | "regulated" | undefined;
|
|
1187
|
+
strictEgress?: boolean | undefined;
|
|
1188
|
+
}>;
|
|
1189
|
+
/**
|
|
1190
|
+
* The strict-egress allow-list (`VpnJobConfig.egress`; docs in vpn-egress.ts).
|
|
1191
|
+
* Field-level shape and size bounds only; the host rules (no IP literals, no
|
|
1192
|
+
* bare `*`, no trailing dot ...) live in `validateVpnEgressPolicy` so the
|
|
1193
|
+
* server, the CLI and the agent apply the identical checks and report every
|
|
1194
|
+
* problem at once. Tunnel settings (PR-D) will embed this.
|
|
1195
|
+
*/
|
|
1196
|
+
export declare const vpnEgressPolicySchema: z.ZodObject<{
|
|
1197
|
+
allow: z.ZodArray<z.ZodObject<{
|
|
1198
|
+
host: z.ZodString;
|
|
1199
|
+
ports: z.ZodOptional<z.ZodArray<z.ZodNumber, "many">>;
|
|
1200
|
+
}, "strip", z.ZodTypeAny, {
|
|
1201
|
+
host: string;
|
|
1202
|
+
ports?: number[] | undefined;
|
|
1203
|
+
}, {
|
|
1204
|
+
host: string;
|
|
1205
|
+
ports?: number[] | undefined;
|
|
1206
|
+
}>, "many">;
|
|
1207
|
+
}, "strip", z.ZodTypeAny, {
|
|
1208
|
+
allow: {
|
|
1209
|
+
host: string;
|
|
1210
|
+
ports?: number[] | undefined;
|
|
1211
|
+
}[];
|
|
1212
|
+
}, {
|
|
1213
|
+
allow: {
|
|
1214
|
+
host: string;
|
|
1215
|
+
ports?: number[] | undefined;
|
|
1216
|
+
}[];
|
|
882
1217
|
}>;
|
|
883
1218
|
/** `POST /agents/vpn/report` (apps/admin-api) — what the agent that holds
|
|
884
1219
|
* an org's tunnel for a build tells the control plane about it. The
|
package/dist/schemas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
|
package/dist/schemas.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { ENFORCEMENT_LEVELS, MAX_VPN_FEATURES, VPN_FEATURE_ID_PATTERN, VPN_HOST_POLICIES } from "./agent-readiness.js";
|
|
3
|
+
import { VPN_COMPLIANCE_MODES, VPN_EGRESS_MAX_CUSTOM_RULES, VPN_EGRESS_MAX_PRESETS, validateEgressSettings } from "./vpn-egress-presets.js";
|
|
2
4
|
export const platformSchema = z.enum(["ios", "android", "flutter", "react-native"]);
|
|
3
5
|
export const appforgeWorkflowSchema = z.object({
|
|
4
6
|
name: z.string().optional(),
|
|
@@ -456,6 +458,20 @@ export const agentHeartbeatSchema = z.object({
|
|
|
456
458
|
* predates the VPN feature omits it and stays `vpnCapable = 0`, so it
|
|
457
459
|
* is never offered a VPN build. */
|
|
458
460
|
vpnCapable: z.boolean().optional(),
|
|
461
|
+
/** VPN features this agent can enforce (migrations/0043) — ids matching
|
|
462
|
+
* `VPN_FEATURE_ID_PATTERN`, at most `MAX_VPN_FEATURES`. Like `vpnCapable`
|
|
463
|
+
* the stored value is derived from THIS heartbeat alone: omitting it (an
|
|
464
|
+
* older agent) means "no features", never "keep the last value". A
|
|
465
|
+
* malformed list is rejected (400) rather than half-trusted. */
|
|
466
|
+
vpnFeatures: z.array(z.string().regex(VPN_FEATURE_ID_PATTERN)).max(MAX_VPN_FEATURES).optional(),
|
|
467
|
+
/** Build-isolation level this agent enforces (migrations/0043). Same
|
|
468
|
+
* omit-means-default (`none`) rule as `vpnFeatures`. */
|
|
469
|
+
enforcementLevel: z.enum(ENFORCEMENT_LEVELS).optional(),
|
|
470
|
+
/** Whether a GitHub Actions self-hosted runner shares this machine
|
|
471
|
+
* (migrations/0047). Like `vpnFeatures`, stored from THIS heartbeat alone:
|
|
472
|
+
* omitted (an older agent, or a check that failed) means "unknown", never
|
|
473
|
+
* "keep the last value", and unknown refuses a dedicated host. */
|
|
474
|
+
coHostedRunner: z.boolean().optional(),
|
|
459
475
|
});
|
|
460
476
|
// `POST /builds/:buildId/logs` (apps/admin-api/src/routes/agents.ts) —
|
|
461
477
|
// one call per flushed line/burst from `packages/agent/src/lib/
|
|
@@ -543,6 +559,21 @@ export const setAgentRemoteControlSchema = z.object({
|
|
|
543
559
|
export const setAgentVpnApprovedSchema = z.object({
|
|
544
560
|
approved: z.boolean(),
|
|
545
561
|
});
|
|
562
|
+
/** `PATCH /orgs/:orgId/agents/:agentId/dedicated` (apps/admin-api) — the
|
|
563
|
+
* only way `Agent.dedicatedOrgId` ever changes (migrations/0043). An
|
|
564
|
+
* operator taint, deliberately not in agentHeartbeatSchema/agentEnrollSchema:
|
|
565
|
+
* an agent must never be able to widen or lift its own restriction. `null`
|
|
566
|
+
* clears it (the Mac goes back to being shared). */
|
|
567
|
+
export const setAgentDedicatedOrgSchema = z.object({
|
|
568
|
+
dedicatedOrgId: z.string().min(1).max(128).nullable(),
|
|
569
|
+
});
|
|
570
|
+
/** `PATCH /orgs/:orgId/vpn-hosts/:tunnelOrgId/policy` (apps/admin-api, platform
|
|
571
|
+
* admins only) — the only way `VpnTunnel.hostPolicy` ever changes
|
|
572
|
+
* (migrations/0047). Deliberately not in `updateVpnTunnelSchema`: an org
|
|
573
|
+
* admin must not be able to loosen the placement the operator set. */
|
|
574
|
+
export const setVpnHostPolicySchema = z.object({
|
|
575
|
+
hostPolicy: z.enum(VPN_HOST_POLICIES),
|
|
576
|
+
});
|
|
546
577
|
/** `PATCH /orgs/:orgId/agents/:agentId/device-stream-hostname` (apps/
|
|
547
578
|
* admin-api)'s request body — `hostname: null` clears it, going back
|
|
548
579
|
* to the global DEVICE_STREAM_WS_URL fallback (see migrations/0034's
|
|
@@ -569,7 +600,45 @@ export const startVncSessionSchema = z.object({
|
|
|
569
600
|
// and the route all apply the identical checks, with every problem
|
|
570
601
|
// reported at once.
|
|
571
602
|
const vpnNameSchema = z.string().min(1).max(64, "must be at most 64 characters");
|
|
572
|
-
|
|
603
|
+
/**
|
|
604
|
+
* The egress-policy fields of a tunnel (migrations/0045), shared by create and
|
|
605
|
+
* update. The field shapes here are shape and size bounds only; which preset ids
|
|
606
|
+
* exist and which hosts are acceptable (no bare `*`, no IP literals ...) is
|
|
607
|
+
* `validateEgressSettings` (vpn-egress-presets.ts), which `refineVpnEgressSettings`
|
|
608
|
+
* applies on top so a caller that relies on these schemas alone cannot accept
|
|
609
|
+
* what the route would refuse. Whether `regulated` may be set at all is the
|
|
610
|
+
* route's call (an operator flag), not the schema's.
|
|
611
|
+
*/
|
|
612
|
+
const vpnEgressSettingsFields = {
|
|
613
|
+
/** `regulated` needs `strictEgress`, and the operator's REGULATED_VPN_ENABLED flag. */
|
|
614
|
+
complianceMode: z.enum(VPN_COMPLIANCE_MODES).optional(),
|
|
615
|
+
strictEgress: z.boolean().optional(),
|
|
616
|
+
/** Preset ids; replaces the list. */
|
|
617
|
+
egressPresets: z.array(z.string().min(1).max(64)).max(VPN_EGRESS_MAX_PRESETS).optional(),
|
|
618
|
+
/** Custom hosts (exact or `*.suffix`, port 443 unless `ports` says otherwise); replaces the list. */
|
|
619
|
+
egressAllow: z
|
|
620
|
+
.array(z.object({
|
|
621
|
+
host: z.string().min(1).max(253),
|
|
622
|
+
ports: z.array(z.number().int().min(1).max(65535)).max(16).optional(),
|
|
623
|
+
}))
|
|
624
|
+
.max(VPN_EGRESS_MAX_CUSTOM_RULES)
|
|
625
|
+
.optional(),
|
|
626
|
+
};
|
|
627
|
+
/** Adds `validateEgressSettings`' host/preset/merge rules to a tunnel schema. Problem strings never echo a rejected value. */
|
|
628
|
+
function refineVpnEgressSettings(input, ctx) {
|
|
629
|
+
for (const message of validateEgressSettings({ egressPresets: input.egressPresets, egressAllow: input.egressAllow })) {
|
|
630
|
+
const field = message.startsWith("egressPresets") ? "egressPresets" : message.startsWith("egressAllow") ? "egressAllow" : null;
|
|
631
|
+
ctx.addIssue({ code: z.ZodIssueCode.custom, message, path: field ? [field] : [] });
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* The shape-only form of the create/update bodies, WITHOUT the egress rules. The
|
|
636
|
+
* API route parses with these and then runs `resolveEgressChange`, which applies
|
|
637
|
+
* the same `validateEgressSettings` but answers with a structured 400 listing
|
|
638
|
+
* every problem (`errors`) rather than a generic schema error. Anything else
|
|
639
|
+
* should use `createVpnTunnelSchema` / `updateVpnTunnelSchema` below.
|
|
640
|
+
*/
|
|
641
|
+
export const createVpnTunnelBodySchema = z.object({
|
|
573
642
|
name: vpnNameSchema,
|
|
574
643
|
gatewayEndpoint: z.string().min(1).max(300),
|
|
575
644
|
gatewayPublicKey: z.string().min(1).max(64),
|
|
@@ -582,8 +651,9 @@ export const createVpnTunnelSchema = z.object({
|
|
|
582
651
|
/** Lab mode — allow a private (RFC1918/CGNAT) gateway endpoint. Setting it
|
|
583
652
|
* `true` is platform-admin only (enforced by the route, not here). */
|
|
584
653
|
allowPrivateEndpoint: z.boolean().optional(),
|
|
654
|
+
...vpnEgressSettingsFields,
|
|
585
655
|
});
|
|
586
|
-
export const
|
|
656
|
+
export const updateVpnTunnelBodySchema = z.object({
|
|
587
657
|
name: vpnNameSchema.optional(),
|
|
588
658
|
gatewayEndpoint: z.string().min(1).max(300).optional(),
|
|
589
659
|
gatewayPublicKey: z.string().min(1).max(64).optional(),
|
|
@@ -598,6 +668,26 @@ export const updateVpnTunnelSchema = z.object({
|
|
|
598
668
|
* instead of queueing); `true` re-enables it, back to `pending` until
|
|
599
669
|
* the next handshake proves it works. */
|
|
600
670
|
enabled: z.boolean().optional(),
|
|
671
|
+
...vpnEgressSettingsFields,
|
|
672
|
+
});
|
|
673
|
+
/** The create body, with the egress rules (bare `*`, IP literals, unknown presets, merged port limit) enforced too. */
|
|
674
|
+
export const createVpnTunnelSchema = createVpnTunnelBodySchema.superRefine(refineVpnEgressSettings);
|
|
675
|
+
/** The update body, with the egress rules enforced too. */
|
|
676
|
+
export const updateVpnTunnelSchema = updateVpnTunnelBodySchema.superRefine(refineVpnEgressSettings);
|
|
677
|
+
/**
|
|
678
|
+
* The strict-egress allow-list (`VpnJobConfig.egress`; docs in vpn-egress.ts).
|
|
679
|
+
* Field-level shape and size bounds only; the host rules (no IP literals, no
|
|
680
|
+
* bare `*`, no trailing dot ...) live in `validateVpnEgressPolicy` so the
|
|
681
|
+
* server, the CLI and the agent apply the identical checks and report every
|
|
682
|
+
* problem at once. Tunnel settings (PR-D) will embed this.
|
|
683
|
+
*/
|
|
684
|
+
export const vpnEgressPolicySchema = z.object({
|
|
685
|
+
allow: z
|
|
686
|
+
.array(z.object({
|
|
687
|
+
host: z.string().min(1).max(253),
|
|
688
|
+
ports: z.array(z.number().int().min(1).max(65535)).max(16).optional(),
|
|
689
|
+
}))
|
|
690
|
+
.max(512),
|
|
601
691
|
});
|
|
602
692
|
/** `POST /agents/vpn/report` (apps/admin-api) — what the agent that holds
|
|
603
693
|
* an org's tunnel for a build tells the control plane about it. The
|