@cobaltcore-dev/aurora 0.5.0 → 0.7.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.
Files changed (116) hide show
  1. package/README.md +59 -13
  2. package/dist/client/{ContentHeader-xQVhO2yT.mjs → ContentHeader-kx1Th5Sq.mjs} +18 -18
  3. package/dist/client/{ContentHeader-xQVhO2yT.mjs.map → ContentHeader-kx1Th5Sq.mjs.map} +1 -1
  4. package/dist/client/{DeleteFlavorModal-CHTUZ3YV.mjs → DeleteFlavorModal-C3cb7YiJ.mjs} +155 -155
  5. package/dist/client/{DeleteFlavorModal-CHTUZ3YV.mjs.map → DeleteFlavorModal-C3cb7YiJ.mjs.map} +1 -1
  6. package/dist/client/{EditSecurityGroupModal-CWHHx2Xk.mjs → EditSecurityGroupModal-CpP54WIK.mjs} +18 -18
  7. package/dist/client/{EditSecurityGroupModal-CWHHx2Xk.mjs.map → EditSecurityGroupModal-CpP54WIK.mjs.map} +1 -1
  8. package/dist/client/{FiltersInput-UKJpNFdr.mjs → FiltersInput-DxcyR6Bp.mjs} +18 -18
  9. package/dist/client/{FiltersInput-UKJpNFdr.mjs.map → FiltersInput-DxcyR6Bp.mjs.map} +1 -1
  10. package/dist/client/{FloatingIpActionModals-caXn6bYo.mjs → FloatingIpActionModals-BP8RWHbu.mjs} +55 -55
  11. package/dist/client/{FloatingIpActionModals-caXn6bYo.mjs.map → FloatingIpActionModals-BP8RWHbu.mjs.map} +1 -1
  12. package/dist/client/{ImageToastNotifications-BWimIzu_.mjs → ImageToastNotifications-TZ3EfQg-.mjs} +323 -371
  13. package/dist/client/ImageToastNotifications-TZ3EfQg-.mjs.map +1 -0
  14. package/dist/client/{RouteError-CUj_m3gu.mjs → RouteError-QSV7qOoJ.mjs} +2 -2
  15. package/dist/client/{RouteError-CUj_m3gu.mjs.map → RouteError-QSV7qOoJ.mjs.map} +1 -1
  16. package/dist/client/{SortInput-GQlQBlAj.mjs → SortInput-CYv2_Pur.mjs} +5 -5
  17. package/dist/client/{SortInput-GQlQBlAj.mjs.map → SortInput-CYv2_Pur.mjs.map} +1 -1
  18. package/dist/client/_auth-DXJkv9QO.mjs.map +1 -1
  19. package/dist/client/{_flavorId-sUWG0xuy.mjs → _flavorId-C2x43-6S.mjs} +9 -9
  20. package/dist/client/{_flavorId-sUWG0xuy.mjs.map → _flavorId-C2x43-6S.mjs.map} +1 -1
  21. package/dist/client/{_flavorId-C5dc1N_j.mjs → _flavorId-CR8ZUI-P.mjs} +46 -46
  22. package/dist/client/{_flavorId-C5dc1N_j.mjs.map → _flavorId-CR8ZUI-P.mjs.map} +1 -1
  23. package/dist/client/{_floatingIpId-CT4y-60o.mjs → _floatingIpId-BCk41_Lb.mjs} +2 -2
  24. package/dist/client/{_floatingIpId-CT4y-60o.mjs.map → _floatingIpId-BCk41_Lb.mjs.map} +1 -1
  25. package/dist/client/{_floatingIpId-COK_TBrz2.mjs → _floatingIpId-BGrOAmPT.mjs} +33 -33
  26. package/dist/client/_floatingIpId-BGrOAmPT.mjs.map +1 -0
  27. package/dist/client/_imageId-CvfD832b.mjs +534 -0
  28. package/dist/client/{_imageId-n3RcnhAR.mjs.map → _imageId-CvfD832b.mjs.map} +1 -1
  29. package/dist/client/_pcaId-BxBt5DXi.mjs +459 -0
  30. package/dist/client/_pcaId-BxBt5DXi.mjs.map +1 -0
  31. package/dist/client/{_pcaId-ChnM_t-9.mjs → _pcaId-DOHycvCf.mjs} +2 -2
  32. package/dist/client/{_pcaId-ChnM_t-9.mjs.map → _pcaId-DOHycvCf.mjs.map} +1 -1
  33. package/dist/client/{_projectId-26bw-_rm.mjs → _projectId-BDSWnMGj.mjs} +3 -3
  34. package/dist/client/{_projectId-26bw-_rm.mjs.map → _projectId-BDSWnMGj.mjs.map} +1 -1
  35. package/dist/client/{_projectId-Dhb4AyBD.mjs → _projectId-DOgwFiqD.mjs} +2 -2
  36. package/dist/client/{_projectId-Dhb4AyBD.mjs.map → _projectId-DOgwFiqD.mjs.map} +1 -1
  37. package/dist/client/_projectId-DS4nR59B.mjs +299 -0
  38. package/dist/client/_projectId-DS4nR59B.mjs.map +1 -0
  39. package/dist/client/{_projectId-BK9UqeYw.mjs → _projectId-MxcHrXW4.mjs} +12 -12
  40. package/dist/client/_projectId-MxcHrXW4.mjs.map +1 -0
  41. package/dist/client/{_securityGroupId-CR1mKICQ.mjs → _securityGroupId-CJJanWiY.mjs} +2 -2
  42. package/dist/client/{_securityGroupId-CR1mKICQ.mjs.map → _securityGroupId-CJJanWiY.mjs.map} +1 -1
  43. package/dist/client/{_securityGroupId-DroYG6cA.mjs → _securityGroupId-KKw4RPdH.mjs} +328 -328
  44. package/dist/client/{_securityGroupId-DroYG6cA.mjs.map → _securityGroupId-KKw4RPdH.mjs.map} +1 -1
  45. package/dist/client/{containers-DGY2hoWw.mjs → _storageType-4wSxI__0.mjs} +18 -15
  46. package/dist/client/_storageType-4wSxI__0.mjs.map +1 -0
  47. package/dist/client/{containers-ZMFTRaQL.mjs → _storageType-DYjo-6ej.mjs} +1054 -1088
  48. package/dist/client/_storageType-DYjo-6ej.mjs.map +1 -0
  49. package/dist/client/{containers-xfsYgRyf.mjs → _storageType-zeSZe--V.mjs} +2 -2
  50. package/dist/client/_storageType-zeSZe--V.mjs.map +1 -0
  51. package/dist/client/{about-969pIiZ9.mjs → about-Bo9vxGHy.mjs} +8 -8
  52. package/dist/client/{about-969pIiZ9.mjs.map → about-Bo9vxGHy.mjs.map} +1 -1
  53. package/dist/client/{build-DracvfrJ.mjs → build-DeJcDjPi.mjs} +3798 -3372
  54. package/dist/client/build-DeJcDjPi.mjs.map +1 -0
  55. package/dist/client/constants-BmcGYeR-.mjs +153 -0
  56. package/dist/client/constants-BmcGYeR-.mjs.map +1 -0
  57. package/dist/client/{flavors-C4GtoybP.mjs → flavors-BxFVqgnb.mjs} +2 -2
  58. package/dist/client/{flavors-C4GtoybP.mjs.map → flavors-BxFVqgnb.mjs.map} +1 -1
  59. package/dist/client/{flavors-CpirO_nr.mjs → flavors-CfdgjsZY.mjs} +192 -192
  60. package/dist/client/{flavors-CpirO_nr.mjs.map → flavors-CfdgjsZY.mjs.map} +1 -1
  61. package/dist/client/{floatingips-BUf_oLRl.mjs → floatingips-ByRb82wS.mjs} +123 -123
  62. package/dist/client/{floatingips-BUf_oLRl.mjs.map → floatingips-ByRb82wS.mjs.map} +1 -1
  63. package/dist/client/{images-Da1t5KPh.mjs → images-CKqIXUq52.mjs} +613 -613
  64. package/dist/client/images-CKqIXUq52.mjs.map +1 -0
  65. package/dist/client/{images-CsonlmFx.mjs → images-C_dX7nY6.mjs} +2 -2
  66. package/dist/client/{images-CsonlmFx.mjs.map → images-C_dX7nY6.mjs.map} +1 -1
  67. package/dist/client/{images-QnWf63uj.mjs → images-CenluYV8.mjs} +2 -2
  68. package/dist/client/{images-QnWf63uj.mjs.map → images-CenluYV8.mjs.map} +1 -1
  69. package/dist/client/index.js +391 -431
  70. package/dist/client/index.js.map +1 -1
  71. package/dist/client/{md-sBiSNVSQ.mjs → md-CYTrL5dq.mjs} +52 -16
  72. package/dist/client/{md-sBiSNVSQ.mjs.map → md-CYTrL5dq.mjs.map} +1 -1
  73. package/dist/client/{objects-H0NN_Sja.mjs → objects-BJM6YeuF.mjs} +2131 -1883
  74. package/dist/client/objects-BJM6YeuF.mjs.map +1 -0
  75. package/dist/client/{objects-B89dYCBq.mjs → objects-gxSjvbvF.mjs} +36 -21
  76. package/dist/client/objects-gxSjvbvF.mjs.map +1 -0
  77. package/dist/client/{objects-CuFLUOe1.mjs → objects-o2Cj_ndZ.mjs} +2 -2
  78. package/dist/client/objects-o2Cj_ndZ.mjs.map +1 -0
  79. package/dist/client/{pca-CtU6REww.mjs → pca-Bl8NmoVZ.mjs} +2 -2
  80. package/dist/client/{pca-CtU6REww.mjs.map → pca-Bl8NmoVZ.mjs.map} +1 -1
  81. package/dist/client/pca-RSiWpJs9.mjs +182 -0
  82. package/dist/client/pca-RSiWpJs9.mjs.map +1 -0
  83. package/dist/client/{projects-DNXsDnJM.mjs → projects-CgclWI16.mjs} +33 -27
  84. package/dist/client/{projects-DNXsDnJM.mjs.map → projects-CgclWI16.mjs.map} +1 -1
  85. package/dist/client/{projects-dhnQkuvV.mjs → projects-D2iewAzu.mjs} +2 -2
  86. package/dist/client/{projects-dhnQkuvV.mjs.map → projects-D2iewAzu.mjs.map} +1 -1
  87. package/dist/client/{projects-C-sjd9T5.mjs → projects-pe2_dCnV.mjs} +2 -2
  88. package/dist/client/{projects-C-sjd9T5.mjs.map → projects-pe2_dCnV.mjs.map} +1 -1
  89. package/dist/client/projects-yiK0HGSA.mjs.map +1 -1
  90. package/dist/client/{securitygroups-wHdrxZXd.mjs → securitygroups-DahZkVYQ.mjs} +111 -111
  91. package/dist/client/{securitygroups-wHdrxZXd.mjs.map → securitygroups-DahZkVYQ.mjs.map} +1 -1
  92. package/dist/client/{useListWithFiltering-DrgUwXef.mjs → useListWithFiltering-DaYcu5AB.mjs} +12 -12
  93. package/dist/client/{useListWithFiltering-DrgUwXef.mjs.map → useListWithFiltering-DaYcu5AB.mjs.map} +1 -1
  94. package/dist/server/index.d.ts +571 -2
  95. package/dist/server/index.js +29 -211
  96. package/package.json +4 -5
  97. package/dist/client/ImageToastNotifications-BWimIzu_.mjs.map +0 -1
  98. package/dist/client/_floatingIpId-COK_TBrz2.mjs.map +0 -1
  99. package/dist/client/_imageId-n3RcnhAR.mjs +0 -534
  100. package/dist/client/_pcaId-B-f_6kqs.mjs +0 -466
  101. package/dist/client/_pcaId-B-f_6kqs.mjs.map +0 -1
  102. package/dist/client/_projectId-BK9UqeYw.mjs.map +0 -1
  103. package/dist/client/_projectId-CCtpAQ8m.mjs +0 -299
  104. package/dist/client/_projectId-CCtpAQ8m.mjs.map +0 -1
  105. package/dist/client/build-DracvfrJ.mjs.map +0 -1
  106. package/dist/client/constants-4lVQXort.mjs +0 -128
  107. package/dist/client/constants-4lVQXort.mjs.map +0 -1
  108. package/dist/client/containers-DGY2hoWw.mjs.map +0 -1
  109. package/dist/client/containers-ZMFTRaQL.mjs.map +0 -1
  110. package/dist/client/containers-xfsYgRyf.mjs.map +0 -1
  111. package/dist/client/images-Da1t5KPh.mjs.map +0 -1
  112. package/dist/client/objects-B89dYCBq.mjs.map +0 -1
  113. package/dist/client/objects-CuFLUOe1.mjs.map +0 -1
  114. package/dist/client/objects-H0NN_Sja.mjs.map +0 -1
  115. package/dist/client/pca-C-UFjicP.mjs +0 -167
  116. package/dist/client/pca-C-UFjicP.mjs.map +0 -1
@@ -1,4 +1,13 @@
1
- import { FastifyInstance } from 'fastify';
1
+ import * as fastify from 'fastify';
2
+ import { FastifyInstance, FastifyRequest } from 'fastify';
3
+ import * as _trpc_server from '@trpc/server';
4
+ import { AnyRouter } from '@trpc/server';
5
+ import * as _cobaltcore_dev_signal_openstack from '@cobaltcore-dev/signal-openstack';
6
+ import { SignalOpenstackSessionType } from '@cobaltcore-dev/signal-openstack';
7
+ import { ProxyConfig } from './shared-types';
8
+ import * as fastify_types_type_provider from 'fastify/types/type-provider';
9
+ import * as http from 'http';
10
+ import { z } from 'zod';
2
11
 
3
12
  declare module "fastify" {
4
13
  interface FastifyRequest {
@@ -34,8 +43,568 @@ interface AuroraServerConfig {
34
43
  * over the legacy in-tree permission_custom_policies/ directory.
35
44
  */
36
45
  policyDir: string;
46
+ /**
47
+ * Additional tRPC routers to merge into the Aurora router at startup.
48
+ *
49
+ * Routers passed here share the same Fastify request context as the built-in
50
+ * Aurora routers (session cookies, OpenStack client, rescoping helpers).
51
+ *
52
+ * **Requirements:**
53
+ * - Routers MUST be created with the `auroraRouter` function exported from
54
+ * `@cobaltcore-dev/aurora/server`. Using a different `initTRPC` instance
55
+ * produces an incompatible context type and will cause runtime failures when
56
+ * procedures attempt to access `ctx.openstack`, `ctx.validateSession`, etc.
57
+ * - Use `protectedProcedure` (or `projectScopedProcedure` /
58
+ * `domainScopedProcedure`) for any procedure that requires an authenticated
59
+ * session. All of these are exported from `@cobaltcore-dev/aurora/server`.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * import { auroraRouter, protectedProcedure, createServer } from "@cobaltcore-dev/aurora/server"
64
+ * import { z } from "zod"
65
+ *
66
+ * const customRouter = auroraRouter({
67
+ * feedback: protectedProcedure
68
+ * .input(z.object({ message: z.string() }))
69
+ * .mutation(async ({ input }) => ({ status: "received" })),
70
+ * })
71
+ *
72
+ * createServer({ ..., routers: [customRouter] })
73
+ * ```
74
+ */
75
+ routers?: AnyRouter[];
37
76
  }
38
77
 
39
78
  declare function createServer(config: AuroraServerConfig): Promise<FastifyInstance>;
40
79
 
41
- export { type AuroraServerConfig, createServer };
80
+ interface AuroraContext {
81
+ validateSession: () => boolean;
82
+ openstack?: Awaited<SignalOpenstackSessionType>;
83
+ signal: AbortSignal;
84
+ getUserInfo?: () => Promise<{
85
+ availableDomains: Array<{
86
+ id: string;
87
+ name: string;
88
+ }>;
89
+ } | undefined>;
90
+ }
91
+ interface FormFieldData {
92
+ [key: string]: string | string[];
93
+ }
94
+ interface AuroraPortalContext extends AuroraContext {
95
+ req: FastifyRequest;
96
+ /** Normalised identity endpoint (always ends with /) */
97
+ identityEndpoint: string;
98
+ /** Ceph/S3 region from consumer config */
99
+ cephRegion?: string;
100
+ /** Parsed list of image metadata keys excluded from the UI */
101
+ imageMetadataExcludedProperties: string[];
102
+ createSession: (params: {
103
+ user: string;
104
+ password: string;
105
+ domain: string;
106
+ }) => SignalOpenstackSessionType;
107
+ rescopeSession: (scope: {
108
+ projectId?: string;
109
+ domainId?: string;
110
+ }) => Promise<Awaited<SignalOpenstackSessionType | null>>;
111
+ terminateSession: () => Promise<void>;
112
+ formFields?: FormFieldData;
113
+ }
114
+
115
+ interface RequestParams {
116
+ method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD";
117
+ path: string;
118
+ options?: {
119
+ host?: string;
120
+ headers?: Record<string, string>;
121
+ body?: string | object | FormData | Blob | ArrayBuffer | ReadableStream;
122
+ queryParams?: Record<string, string | string[] | number | boolean | null | undefined>;
123
+ signal?: AbortSignal;
124
+ debug?: boolean;
125
+ proxy?: ProxyConfig;
126
+ };
127
+ }
128
+ type ActionBody = NonNullable<RequestParams["options"]>["body"];
129
+ type ActionPath = RequestParams["path"];
130
+
131
+ declare const auroraRouter: _trpc_server.TRPCRouterBuilder<{
132
+ ctx: AuroraPortalContext;
133
+ meta: object;
134
+ errorShape: _trpc_server.TRPCDefaultErrorShape;
135
+ transformer: false;
136
+ }>;
137
+ declare const publicProcedure: _trpc_server.TRPCProcedureBuilder<AuroraPortalContext, object, object, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
138
+ declare const protectedProcedure: _trpc_server.TRPCProcedureBuilder<AuroraPortalContext, object, {
139
+ req: fastify.FastifyRequest<fastify.RouteGenericInterface, fastify.RawServerDefault, http.IncomingMessage, fastify.FastifySchema, fastify.FastifyTypeProviderDefault, unknown, fastify.FastifyBaseLogger, fastify_types_type_provider.ResolveFastifyRequestType<fastify.FastifyTypeProviderDefault, fastify.FastifySchema, fastify.RouteGenericInterface>>;
140
+ signal: AbortSignal;
141
+ createSession: (params: {
142
+ user: string;
143
+ password: string;
144
+ domain: string;
145
+ }) => _cobaltcore_dev_signal_openstack.SignalOpenstackSessionType;
146
+ rescopeSession: (scope: {
147
+ projectId?: string;
148
+ domainId?: string;
149
+ }) => Promise<Awaited<_cobaltcore_dev_signal_openstack.SignalOpenstackSessionType | null>>;
150
+ identityEndpoint: string;
151
+ cephRegion: string | undefined;
152
+ terminateSession: () => Promise<void>;
153
+ validateSession: () => boolean;
154
+ openstack: {
155
+ service: (name: string, serviceDefaultOptions?: _cobaltcore_dev_signal_openstack.SignalOpenstackOptions) => {
156
+ availableEndpoints: () => {
157
+ id: string;
158
+ interface: string;
159
+ region: string;
160
+ region_id: string;
161
+ url: string;
162
+ }[] | undefined;
163
+ getEndpoint: (options?: {
164
+ region?: string;
165
+ interfaceName?: string;
166
+ }) => string | null;
167
+ head: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
168
+ get: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
169
+ post: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
170
+ put: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
171
+ patch: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
172
+ del: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
173
+ cancellableHead: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
174
+ cancellableGet: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
175
+ cancellablePost: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
176
+ cancellablePut: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
177
+ cancellablePatch: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
178
+ cancellableDel: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
179
+ };
180
+ hasService: (name: string) => boolean;
181
+ terminate: () => Promise<void>;
182
+ rescope: (scope: _cobaltcore_dev_signal_openstack.AuthConfig["auth"]["scope"]) => Promise<void>;
183
+ getToken: () => {
184
+ authToken: string;
185
+ tokenData: {
186
+ application_credential?: {
187
+ id: string;
188
+ name: string;
189
+ restricted: boolean;
190
+ };
191
+ audit_ids?: string[];
192
+ catalog?: {
193
+ endpoints: {
194
+ id: string;
195
+ interface: string;
196
+ region: string;
197
+ region_id: string;
198
+ url: string;
199
+ }[];
200
+ type: string;
201
+ id: string;
202
+ name: string;
203
+ }[];
204
+ expires_at: string;
205
+ issued_at: string;
206
+ methods: string[];
207
+ roles: {
208
+ id: string;
209
+ name: string;
210
+ }[];
211
+ system: {
212
+ all: boolean;
213
+ };
214
+ project?: {
215
+ domain?: {
216
+ id?: string;
217
+ name?: string;
218
+ };
219
+ id?: string;
220
+ name?: string;
221
+ };
222
+ domain?: {
223
+ id?: string;
224
+ name?: string;
225
+ };
226
+ user: {
227
+ domain: {
228
+ id: string;
229
+ name: string;
230
+ };
231
+ id: string;
232
+ name: string;
233
+ password_expires_at: string;
234
+ };
235
+ };
236
+ isExpired: () => boolean;
237
+ expiresAtDate: Date;
238
+ availableRegions: string[];
239
+ serviceEndpoint: (nameOrType: string, { region, interfaceName }: {
240
+ region?: string;
241
+ interfaceName: string;
242
+ }) => string | null;
243
+ hasService: (nameOrType: string) => boolean;
244
+ hasRole: (name: string) => boolean;
245
+ } | undefined;
246
+ isValid: () => boolean | "" | undefined;
247
+ } | undefined;
248
+ getUserInfo: (() => Promise<{
249
+ availableDomains: Array<{
250
+ id: string;
251
+ name: string;
252
+ }>;
253
+ } | undefined>) | undefined;
254
+ imageMetadataExcludedProperties: string[];
255
+ formFields: FormFieldData | undefined;
256
+ }, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
257
+ /**
258
+ * Base input schema that all project-scoped procedures must extend
259
+ * Ensures project_id is always present and validated
260
+ */
261
+ declare const projectScopedInputSchema: z.ZodObject<{
262
+ project_id: z.ZodString;
263
+ }, z.core.$strip>;
264
+ /**
265
+ * Base input schema that all domain-scoped procedures must extend
266
+ * Ensures domain_id is always present and validated
267
+ */
268
+ declare const domainScopedInputSchema: z.ZodObject<{
269
+ domain_id: z.ZodString;
270
+ }, z.core.$strip>;
271
+ /**
272
+ * Project-scoped procedure middleware
273
+ *
274
+ * Automatically handles OpenStack token rescoping to a specific project.
275
+ * This middleware ensures that all subsequent API calls have the correct
276
+ * project-scoped token, which is required for accessing project-level resources
277
+ * like compute instances, networks, volumes, etc.
278
+ *
279
+ * Requirements:
280
+ * - User must be authenticated (extends protectedProcedure)
281
+ * - Input is pre-validated with projectScopedInputSchema (base schema applied)
282
+ * - Additional input fields can be added by extending the base schema
283
+ *
284
+ * Behavior:
285
+ * - Validates project_id through Zod schema (no manual validation needed)
286
+ * - Rescopes the OpenStack session to the specified project using Keystone
287
+ * - Caches the scoped token in a cookie to avoid unnecessary rescoping on subsequent requests
288
+ * - Passes the rescoped session to downstream procedures via ctx.openstack
289
+ *
290
+ * Error handling:
291
+ * - BAD_REQUEST: If project_id is missing or invalid (handled by Zod schema)
292
+ * - UNAUTHORIZED: If token rescoping fails, including when the session cannot be
293
+ * rescoped to the specified project (for example, due to an invalid token,
294
+ * Keystone unavailability, or missing role assignment on that project)
295
+ *
296
+ * Usage example:
297
+ * ```ts
298
+ * export const computeRouter = {
299
+ * listServers: projectScopedProcedure
300
+ * .input(projectScopedInputSchema.extend({ limit: z.number().optional() }))
301
+ * .query(async ({ ctx, input }) => {
302
+ * // Token is already rescoped to the project
303
+ * const compute = ctx.openstack.service("compute")
304
+ * return compute.servers.list()
305
+ * })
306
+ * }
307
+ * ```
308
+ *
309
+ * @important When extending the input schema, use projectScopedInputSchema.extend({ ... })
310
+ */
311
+ declare const projectScopedProcedure: _trpc_server.TRPCProcedureBuilder<AuroraPortalContext, object, {
312
+ req: fastify.FastifyRequest<fastify.RouteGenericInterface, fastify.RawServerDefault, http.IncomingMessage, fastify.FastifySchema, fastify.FastifyTypeProviderDefault, unknown, fastify.FastifyBaseLogger, fastify_types_type_provider.ResolveFastifyRequestType<fastify.FastifyTypeProviderDefault, fastify.FastifySchema, fastify.RouteGenericInterface>>;
313
+ signal: AbortSignal;
314
+ createSession: (params: {
315
+ user: string;
316
+ password: string;
317
+ domain: string;
318
+ }) => _cobaltcore_dev_signal_openstack.SignalOpenstackSessionType;
319
+ rescopeSession: (scope: {
320
+ projectId?: string;
321
+ domainId?: string;
322
+ }) => Promise<Awaited<_cobaltcore_dev_signal_openstack.SignalOpenstackSessionType | null>>;
323
+ identityEndpoint: string;
324
+ cephRegion: string | undefined;
325
+ terminateSession: () => Promise<void>;
326
+ validateSession: () => boolean;
327
+ openstack: {
328
+ service: (name: string, serviceDefaultOptions?: _cobaltcore_dev_signal_openstack.SignalOpenstackOptions) => {
329
+ availableEndpoints: () => {
330
+ id: string;
331
+ interface: string;
332
+ region: string;
333
+ region_id: string;
334
+ url: string;
335
+ }[] | undefined;
336
+ getEndpoint: (options?: {
337
+ region?: string;
338
+ interfaceName?: string;
339
+ }) => string | null;
340
+ head: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
341
+ get: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
342
+ post: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
343
+ put: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
344
+ patch: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
345
+ del: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
346
+ cancellableHead: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
347
+ cancellableGet: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
348
+ cancellablePost: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
349
+ cancellablePut: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
350
+ cancellablePatch: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
351
+ cancellableDel: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
352
+ };
353
+ hasService: (name: string) => boolean;
354
+ terminate: () => Promise<void>;
355
+ rescope: (scope: _cobaltcore_dev_signal_openstack.AuthConfig["auth"]["scope"]) => Promise<void>;
356
+ getToken: () => {
357
+ authToken: string;
358
+ tokenData: {
359
+ application_credential?: {
360
+ id: string;
361
+ name: string;
362
+ restricted: boolean;
363
+ };
364
+ audit_ids?: string[];
365
+ catalog?: {
366
+ endpoints: {
367
+ id: string;
368
+ interface: string;
369
+ region: string;
370
+ region_id: string;
371
+ url: string;
372
+ }[];
373
+ type: string;
374
+ id: string;
375
+ name: string;
376
+ }[];
377
+ expires_at: string;
378
+ issued_at: string;
379
+ methods: string[];
380
+ roles: {
381
+ id: string;
382
+ name: string;
383
+ }[];
384
+ system: {
385
+ all: boolean;
386
+ };
387
+ project?: {
388
+ domain?: {
389
+ id?: string;
390
+ name?: string;
391
+ };
392
+ id?: string;
393
+ name?: string;
394
+ };
395
+ domain?: {
396
+ id?: string;
397
+ name?: string;
398
+ };
399
+ user: {
400
+ domain: {
401
+ id: string;
402
+ name: string;
403
+ };
404
+ id: string;
405
+ name: string;
406
+ password_expires_at: string;
407
+ };
408
+ };
409
+ isExpired: () => boolean;
410
+ expiresAtDate: Date;
411
+ availableRegions: string[];
412
+ serviceEndpoint: (nameOrType: string, { region, interfaceName }: {
413
+ region?: string;
414
+ interfaceName: string;
415
+ }) => string | null;
416
+ hasService: (nameOrType: string) => boolean;
417
+ hasRole: (name: string) => boolean;
418
+ } | undefined;
419
+ isValid: () => boolean | "" | undefined;
420
+ };
421
+ getUserInfo: (() => Promise<{
422
+ availableDomains: Array<{
423
+ id: string;
424
+ name: string;
425
+ }>;
426
+ } | undefined>) | undefined;
427
+ imageMetadataExcludedProperties: string[];
428
+ formFields: FormFieldData | undefined;
429
+ }, {
430
+ project_id: string;
431
+ }, {
432
+ project_id: string;
433
+ }, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
434
+ /**
435
+ * Domain-scoped procedure middleware
436
+ *
437
+ * Automatically handles OpenStack token rescoping to a specific domain.
438
+ * This middleware ensures that all subsequent API calls have the correct
439
+ * domain-scoped token, which is required for accessing domain-level resources
440
+ * and performing administrative operations like user management, project creation, etc.
441
+ *
442
+ * Requirements:
443
+ * - User must be authenticated (extends protectedProcedure)
444
+ * - Input is pre-validated with domainScopedInputSchema (base schema applied)
445
+ * - User must have access to the requested domain (validated via lazy-loaded getUserInfo)
446
+ * - Additional input fields can be added by extending the base schema
447
+ *
448
+ * Behavior:
449
+ * - Validates domain_id through Zod schema (no manual validation needed)
450
+ * - Lazy-loads user info (calls /v3/auth/domains) only when this procedure is invoked
451
+ * - Verifies that the domain is in the user's available domains list
452
+ * - Rescopes the OpenStack session to the specified domain using Keystone
453
+ * - Keystone enforces permissions based on user's actual role assignments in that domain
454
+ * - Caches the scoped token in a cookie to avoid unnecessary rescoping on subsequent requests
455
+ * - Passes the rescoped session to downstream procedures via ctx.openstack
456
+ *
457
+ * Performance:
458
+ * - User info is fetched lazily (only when domainScopedProcedure is used)
459
+ * - This avoids unnecessary Keystone API calls for project-scoped or public procedures
460
+ * - User info is cached per session to avoid repeated API calls
461
+ *
462
+ * Error handling:
463
+ * - BAD_REQUEST: If domain_id is missing or invalid (handled by Zod schema)
464
+ * - FORBIDDEN: If user lacks access to the requested domain
465
+ * - UNAUTHORIZED: If token rescoping fails (e.g., invalid token, Keystone unavailable)
466
+ *
467
+ * Note: We don't check for specific role names (like "admin") because OpenStack roles
468
+ * are configurable. Instead, we rely on Keystone to enforce permissions when rescoping.
469
+ *
470
+ * Usage example:
471
+ * ```ts
472
+ * export const identityRouter = {
473
+ * listUsers: domainScopedProcedure
474
+ * .input(domainScopedInputSchema.extend({ includeDisabled: z.boolean().optional() }))
475
+ * .query(async ({ ctx, input }) => {
476
+ * // Token is already rescoped to the domain
477
+ * // Keystone has validated user's permissions in this domain
478
+ * const identity = ctx.openstack.service("identity")
479
+ * return identity.users.list()
480
+ * })
481
+ * }
482
+ * ```
483
+ *
484
+ * @important When extending the input schema, use domainScopedInputSchema.extend({ ... })
485
+ */
486
+ declare const domainScopedProcedure: _trpc_server.TRPCProcedureBuilder<AuroraPortalContext, object, {
487
+ req: fastify.FastifyRequest<fastify.RouteGenericInterface, fastify.RawServerDefault, http.IncomingMessage, fastify.FastifySchema, fastify.FastifyTypeProviderDefault, unknown, fastify.FastifyBaseLogger, fastify_types_type_provider.ResolveFastifyRequestType<fastify.FastifyTypeProviderDefault, fastify.FastifySchema, fastify.RouteGenericInterface>>;
488
+ signal: AbortSignal;
489
+ createSession: (params: {
490
+ user: string;
491
+ password: string;
492
+ domain: string;
493
+ }) => _cobaltcore_dev_signal_openstack.SignalOpenstackSessionType;
494
+ rescopeSession: (scope: {
495
+ projectId?: string;
496
+ domainId?: string;
497
+ }) => Promise<Awaited<_cobaltcore_dev_signal_openstack.SignalOpenstackSessionType | null>>;
498
+ identityEndpoint: string;
499
+ cephRegion: string | undefined;
500
+ terminateSession: () => Promise<void>;
501
+ validateSession: () => boolean;
502
+ openstack: {
503
+ service: (name: string, serviceDefaultOptions?: _cobaltcore_dev_signal_openstack.SignalOpenstackOptions) => {
504
+ availableEndpoints: () => {
505
+ id: string;
506
+ interface: string;
507
+ region: string;
508
+ region_id: string;
509
+ url: string;
510
+ }[] | undefined;
511
+ getEndpoint: (options?: {
512
+ region?: string;
513
+ interfaceName?: string;
514
+ }) => string | null;
515
+ head: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
516
+ get: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
517
+ post: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
518
+ put: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
519
+ patch: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
520
+ del: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => Promise<Response>;
521
+ cancellableHead: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
522
+ cancellableGet: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
523
+ cancellablePost: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
524
+ cancellablePut: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
525
+ cancellablePatch: (path: ActionPath, values: ActionBody, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
526
+ cancellableDel: (path: ActionPath, options?: _cobaltcore_dev_signal_openstack.ServiceActionOptions) => _cobaltcore_dev_signal_openstack.CancellableRequest<Response>;
527
+ };
528
+ hasService: (name: string) => boolean;
529
+ terminate: () => Promise<void>;
530
+ rescope: (scope: _cobaltcore_dev_signal_openstack.AuthConfig["auth"]["scope"]) => Promise<void>;
531
+ getToken: () => {
532
+ authToken: string;
533
+ tokenData: {
534
+ application_credential?: {
535
+ id: string;
536
+ name: string;
537
+ restricted: boolean;
538
+ };
539
+ audit_ids?: string[];
540
+ catalog?: {
541
+ endpoints: {
542
+ id: string;
543
+ interface: string;
544
+ region: string;
545
+ region_id: string;
546
+ url: string;
547
+ }[];
548
+ type: string;
549
+ id: string;
550
+ name: string;
551
+ }[];
552
+ expires_at: string;
553
+ issued_at: string;
554
+ methods: string[];
555
+ roles: {
556
+ id: string;
557
+ name: string;
558
+ }[];
559
+ system: {
560
+ all: boolean;
561
+ };
562
+ project?: {
563
+ domain?: {
564
+ id?: string;
565
+ name?: string;
566
+ };
567
+ id?: string;
568
+ name?: string;
569
+ };
570
+ domain?: {
571
+ id?: string;
572
+ name?: string;
573
+ };
574
+ user: {
575
+ domain: {
576
+ id: string;
577
+ name: string;
578
+ };
579
+ id: string;
580
+ name: string;
581
+ password_expires_at: string;
582
+ };
583
+ };
584
+ isExpired: () => boolean;
585
+ expiresAtDate: Date;
586
+ availableRegions: string[];
587
+ serviceEndpoint: (nameOrType: string, { region, interfaceName }: {
588
+ region?: string;
589
+ interfaceName: string;
590
+ }) => string | null;
591
+ hasService: (nameOrType: string) => boolean;
592
+ hasRole: (name: string) => boolean;
593
+ } | undefined;
594
+ isValid: () => boolean | "" | undefined;
595
+ };
596
+ getUserInfo: (() => Promise<{
597
+ availableDomains: Array<{
598
+ id: string;
599
+ name: string;
600
+ }>;
601
+ } | undefined>) | undefined;
602
+ imageMetadataExcludedProperties: string[];
603
+ formFields: FormFieldData | undefined;
604
+ }, {
605
+ domain_id: string;
606
+ }, {
607
+ domain_id: string;
608
+ }, _trpc_server.TRPCUnsetMarker, _trpc_server.TRPCUnsetMarker, false>;
609
+
610
+ export { type AuroraServerConfig, auroraRouter, createServer, domainScopedInputSchema, domainScopedProcedure, projectScopedInputSchema, projectScopedProcedure, protectedProcedure, publicProcedure };