diff --git a/netlify.toml b/netlify.toml index b99f148146d..0affcd11912 100644 --- a/netlify.toml +++ b/netlify.toml @@ -11,7 +11,7 @@ frame-ancestors *; \ object-src 'none'; \ connect-src https: *.usepylon.com *.posthog.com wss://*.pusher.com; \ - font-src 'self' https://fonts.gstatic.com; + font-src 'self' https://fonts.gstatic.com *.usepylon.com; """ Permissions-Policy = "geolocation=(),midi=(),sync-xhr=(self),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()" Referrer-Policy = "no-referrer" diff --git a/proto/gen/rill/runtime/v1/api.pb.go b/proto/gen/rill/runtime/v1/api.pb.go index e257fee8a38..55bbcf28946 100644 --- a/proto/gen/rill/runtime/v1/api.pb.go +++ b/proto/gen/rill/runtime/v1/api.pb.go @@ -5464,7 +5464,7 @@ var file_rill_runtime_v1_api_proto_rawDesc = []byte{ 0x0a, 0x14, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, - 0x45, 0x10, 0x02, 0x32, 0xeb, 0x21, 0x0a, 0x0e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x53, + 0x45, 0x10, 0x02, 0x32, 0xee, 0x21, 0x0a, 0x0e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, @@ -5728,26 +5728,26 @@ var file_rill_runtime_v1_api_proto_rawDesc = []byte{ 0x12, 0x30, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x73, 0x12, 0x6d, 0x0a, 0x0b, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, + 0x72, 0x73, 0x12, 0x70, 0x0a, 0x0b, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, - 0x76, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x0d, 0x12, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x2d, 0x6a, 0x77, - 0x74, 0x42, 0xbb, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x41, 0x70, 0x69, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x52, 0x58, 0xaa, 0x02, 0x0f, 0x52, 0x69, 0x6c, 0x6c, - 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0f, 0x52, 0x69, - 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1b, - 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x52, 0x69, - 0x6c, 0x6c, 0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x76, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, + 0x2d, 0x6a, 0x77, 0x74, 0x42, 0xbb, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x41, 0x70, + 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, + 0x6c, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, + 0x6c, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x52, 0x58, 0xaa, 0x02, 0x0f, 0x52, + 0x69, 0x6c, 0x6c, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, + 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, + 0xe2, 0x02, 0x1b, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, + 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x11, 0x52, 0x69, 0x6c, 0x6c, 0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, + 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/gen/rill/runtime/v1/api.pb.gw.go b/proto/gen/rill/runtime/v1/api.pb.gw.go index 634af5589de..037878e676f 100644 --- a/proto/gen/rill/runtime/v1/api.pb.gw.go +++ b/proto/gen/rill/runtime/v1/api.pb.gw.go @@ -1606,18 +1606,11 @@ func local_request_RuntimeService_ListNotifierConnectors_0(ctx context.Context, } -var ( - filter_RuntimeService_IssueDevJWT_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} -) - func request_RuntimeService_IssueDevJWT_0(ctx context.Context, marshaler runtime.Marshaler, client RuntimeServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq IssueDevJWTRequest var metadata runtime.ServerMetadata - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RuntimeService_IssueDevJWT_0); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -1630,10 +1623,7 @@ func local_request_RuntimeService_IssueDevJWT_0(ctx context.Context, marshaler r var protoReq IssueDevJWTRequest var metadata runtime.ServerMetadata - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RuntimeService_IssueDevJWT_0); err != nil { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -2344,7 +2334,7 @@ func RegisterRuntimeServiceHandlerServer(ctx context.Context, mux *runtime.Serve }) - mux.Handle("GET", pattern_RuntimeService_IssueDevJWT_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_RuntimeService_IssueDevJWT_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -3070,7 +3060,7 @@ func RegisterRuntimeServiceHandlerClient(ctx context.Context, mux *runtime.Serve }) - mux.Handle("GET", pattern_RuntimeService_IssueDevJWT_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_RuntimeService_IssueDevJWT_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) diff --git a/proto/gen/rill/runtime/v1/api_grpc.pb.go b/proto/gen/rill/runtime/v1/api_grpc.pb.go index 91ca3cf3fa2..c263a5c79ef 100644 --- a/proto/gen/rill/runtime/v1/api_grpc.pb.go +++ b/proto/gen/rill/runtime/v1/api_grpc.pb.go @@ -61,7 +61,9 @@ const ( type RuntimeServiceClient interface { // Ping returns information about the runtime Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) + // Health runs a health check on the runtime. Health(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error) + // InstanceHealth runs a health check on a specific instance. InstanceHealth(ctx context.Context, in *InstanceHealthRequest, opts ...grpc.CallOption) (*InstanceHealthResponse, error) // ListInstances lists all the instances currently managed by the runtime ListInstances(ctx context.Context, in *ListInstancesRequest, opts ...grpc.CallOption) (*ListInstancesResponse, error) @@ -121,6 +123,7 @@ type RuntimeServiceClient interface { // ListNotifierConnectors returns the names of all configured connectors that can be used as notifiers. // This API is much faster than AnalyzeConnectors and can be called without admin-level permissions. ListNotifierConnectors(ctx context.Context, in *ListNotifierConnectorsRequest, opts ...grpc.CallOption) (*ListNotifierConnectorsResponse, error) + // IssueDevJWT issues a JWT for mimicking a user in local development. IssueDevJWT(ctx context.Context, in *IssueDevJWTRequest, opts ...grpc.CallOption) (*IssueDevJWTResponse, error) } @@ -520,7 +523,9 @@ func (c *runtimeServiceClient) IssueDevJWT(ctx context.Context, in *IssueDevJWTR type RuntimeServiceServer interface { // Ping returns information about the runtime Ping(context.Context, *PingRequest) (*PingResponse, error) + // Health runs a health check on the runtime. Health(context.Context, *HealthRequest) (*HealthResponse, error) + // InstanceHealth runs a health check on a specific instance. InstanceHealth(context.Context, *InstanceHealthRequest) (*InstanceHealthResponse, error) // ListInstances lists all the instances currently managed by the runtime ListInstances(context.Context, *ListInstancesRequest) (*ListInstancesResponse, error) @@ -580,6 +585,7 @@ type RuntimeServiceServer interface { // ListNotifierConnectors returns the names of all configured connectors that can be used as notifiers. // This API is much faster than AnalyzeConnectors and can be called without admin-level permissions. ListNotifierConnectors(context.Context, *ListNotifierConnectorsRequest) (*ListNotifierConnectorsResponse, error) + // IssueDevJWT issues a JWT for mimicking a user in local development. IssueDevJWT(context.Context, *IssueDevJWTRequest) (*IssueDevJWTResponse, error) mustEmbedUnimplementedRuntimeServiceServer() } diff --git a/proto/gen/rill/runtime/v1/runtime.swagger.yaml b/proto/gen/rill/runtime/v1/runtime.swagger.yaml index 4f055c9e1d4..9f68165e708 100644 --- a/proto/gen/rill/runtime/v1/runtime.swagger.yaml +++ b/proto/gen/rill/runtime/v1/runtime.swagger.yaml @@ -135,7 +135,8 @@ paths: tags: - ConnectorService /v1/dev-jwt: - get: + post: + summary: IssueDevJWT issues a JWT for mimicking a user in local development. operationId: RuntimeService_IssueDevJWT responses: "200": @@ -147,25 +148,11 @@ paths: schema: $ref: '#/definitions/rpcStatus' parameters: - - name: name - in: query - required: false - type: string - - name: email - in: query - required: false - type: string - - name: groups - in: query - required: false - type: array - items: - type: string - collectionFormat: multi - - name: admin - in: query - required: false - type: boolean + - name: body + in: body + required: true + schema: + $ref: '#/definitions/v1IssueDevJWTRequest' tags: - RuntimeService /v1/examples: @@ -295,6 +282,7 @@ paths: - ConnectorService /v1/health: get: + summary: Health runs a health check on the runtime. operationId: RuntimeService_Health responses: "200": @@ -309,6 +297,7 @@ paths: - RuntimeService /v1/health/instances/{instanceId}: get: + summary: InstanceHealth runs a health check on a specific instance. operationId: RuntimeService_InstanceHealth responses: "200": @@ -3958,6 +3947,20 @@ definitions: properties: instanceHealth: $ref: '#/definitions/v1InstanceHealth' + v1IssueDevJWTRequest: + type: object + properties: + name: + type: string + email: + type: string + groups: + type: array + items: + type: string + admin: + type: boolean + title: Request message for RuntimeService.IssueDevJWT v1IssueDevJWTResponse: type: object properties: diff --git a/proto/rill/runtime/v1/api.proto b/proto/rill/runtime/v1/api.proto index 4388ed6ad58..cca64b34677 100644 --- a/proto/rill/runtime/v1/api.proto +++ b/proto/rill/runtime/v1/api.proto @@ -15,10 +15,12 @@ service RuntimeService { option (google.api.http) = {get: "/v1/ping"}; } + // Health runs a health check on the runtime. rpc Health(HealthRequest) returns (HealthResponse) { option (google.api.http) = {get: "/v1/health"}; } + // InstanceHealth runs a health check on a specific instance. rpc InstanceHealth(InstanceHealthRequest) returns (InstanceHealthResponse) { option (google.api.http) = {get: "/v1/health/instances/{instance_id}"}; } @@ -206,8 +208,14 @@ service RuntimeService { option (google.api.http) = {get: "/v1/instances/{instance_id}/connectors/notifiers"}; } + // Access management + + // IssueDevJWT issues a JWT for mimicking a user in local development. rpc IssueDevJWT(IssueDevJWTRequest) returns (IssueDevJWTResponse) { - option (google.api.http) = {get: "/v1/dev-jwt"}; + option (google.api.http) = { + post: "/v1/dev-jwt", + body: "*" + }; } } diff --git a/runtime/drivers/druid/druidsqldriver/druid_api_sql_driver.go b/runtime/drivers/druid/druidsqldriver/druid_api_sql_driver.go index e0afed3d032..4f366a43b83 100644 --- a/runtime/drivers/druid/druidsqldriver/druid_api_sql_driver.go +++ b/runtime/drivers/druid/druidsqldriver/druid_api_sql_driver.go @@ -74,6 +74,13 @@ func (c *sqlConnection) QueryContext(ctx context.Context, query string, args []d return nil, err } + // Druid sends well-formed response for 200, 400 and 500 status codes, for others use this + // ref - https://druid.apache.org/docs/latest/api-reference/sql-api/#responses + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusBadRequest && resp.StatusCode != http.StatusInternalServerError { + resp.Body.Close() + return nil, fmt.Errorf("unexpected status code: %d, status: %s", resp.StatusCode, resp.Status) + } + dec := json.NewDecoder(resp.Body) var obj any diff --git a/web-admin/src/features/dashboards/share/ShareDashboardButton.svelte b/web-admin/src/features/dashboards/share/ShareDashboardButton.svelte index 7b6df580c4d..c7d1caec21e 100644 --- a/web-admin/src/features/dashboards/share/ShareDashboardButton.svelte +++ b/web-admin/src/features/dashboards/share/ShareDashboardButton.svelte @@ -14,6 +14,8 @@ TabsTrigger, } from "@rilldata/web-common/components/tabs"; import { copyToClipboard } from "@rilldata/web-common/lib/actions/copy-to-clipboard"; + + export let createMagicAuthTokens: boolean; @@ -24,7 +26,9 @@ Copy link - Create public link + {#if createMagicAuthTokens} + Create public link + {/if}
diff --git a/web-admin/src/features/navigation/TopNavigationBar.svelte b/web-admin/src/features/navigation/TopNavigationBar.svelte index cab615a93a6..a2a163e97fa 100644 --- a/web-admin/src/features/navigation/TopNavigationBar.svelte +++ b/web-admin/src/features/navigation/TopNavigationBar.svelte @@ -31,6 +31,8 @@ isProjectPage, } from "./nav-utils"; + export let createMagicAuthTokens: boolean; + const user = createAdminServiceGetCurrentUser(); $: instanceId = $runtime?.instanceId; @@ -175,7 +177,7 @@ {#if $user.isSuccess && $user.data.user && !onMagicLinkPage} - + {/if} {/if} diff --git a/web-admin/src/routes/+layout.svelte b/web-admin/src/routes/+layout.svelte index ac59bc24157..8415a71f06b 100644 --- a/web-admin/src/routes/+layout.svelte +++ b/web-admin/src/routes/+layout.svelte @@ -14,6 +14,10 @@ import { initPylonWidget } from "../features/help/initPylonWidget"; import TopNavigationBar from "../features/navigation/TopNavigationBar.svelte"; + export let data; + + $: ({ projectPermissions } = data); + // Motivation: // - https://tkdodo.eu/blog/breaking-react-querys-api-on-purpose#a-bad-api // - https://tkdodo.eu/blog/react-query-error-handling#the-global-callbacks @@ -49,7 +53,9 @@
{#if !isEmbed} - + {/if} diff --git a/web-admin/src/routes/+layout.ts b/web-admin/src/routes/+layout.ts index 14cf4be0a24..412e18466f4 100644 --- a/web-admin/src/routes/+layout.ts +++ b/web-admin/src/routes/+layout.ts @@ -4,3 +4,68 @@ app in production. Here, we are setting server-side rendering (SSR) to false to ensure the same single-page app behavior in development. */ export const ssr = false; + +import type { V1ProjectPermissions } from "@rilldata/web-admin/client"; +import { adminServiceGetProject } from "@rilldata/web-admin/client/index.js"; +import { getAdminServiceGetProjectQueryKey } from "@rilldata/web-admin/client/index.js"; +import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient.js"; +import { error } from "@sveltejs/kit"; +import type { QueryFunction, QueryKey } from "@tanstack/svelte-query"; +import { + adminServiceGetProjectWithBearerToken, + getAdminServiceGetProjectWithBearerTokenQueryKey, +} from "../features/shareable-urls/get-project-with-bearer-token.js"; + +export const load = async ({ params }) => { + const { organization, project, token } = params; + + if (!organization || !project) { + return { + projectPermissions: {}, + }; + } + + let queryKey: QueryKey; + let queryFn: QueryFunction< + Awaited> + >; + + if (token) { + queryKey = getAdminServiceGetProjectWithBearerTokenQueryKey( + organization, + project, + token, + {}, + ); + + queryFn = ({ signal }) => + adminServiceGetProjectWithBearerToken( + organization, + project, + token, + {}, + signal, + ); + } else { + queryKey = getAdminServiceGetProjectQueryKey(organization, project); + + queryFn = ({ signal }) => + adminServiceGetProject(organization, project, {}, signal); + } + + try { + const response = await queryClient.fetchQuery({ + queryFn, + queryKey, + }); + + const { projectPermissions } = response; + + return { + projectPermissions, + }; + } catch (e) { + console.error(e); + throw error(e.response.status, "Error fetching deployment"); + } +}; diff --git a/web-admin/src/routes/[organization]/[project]/+layout.svelte b/web-admin/src/routes/[organization]/[project]/+layout.svelte index d7409b515e2..8dbf0763c28 100644 --- a/web-admin/src/routes/[organization]/[project]/+layout.svelte +++ b/web-admin/src/routes/[organization]/[project]/+layout.svelte @@ -76,8 +76,6 @@ query: baseGetProjectQueryOptions, }, ); - $: ({ data: cookieProjectData, error: cookieProjectError } = - $cookieProjectQuery); /** * `GetProject` with token-based auth. @@ -93,8 +91,8 @@ query: baseGetProjectQueryOptions, }, ); - $: ({ data: tokenProjectData, error: tokenProjectError } = - $tokenProjectQuery); + + $: projectQuery = onMagicLinkPage ? tokenProjectQuery : cookieProjectQuery; /** * `GetDeploymentCredentials` @@ -123,11 +121,10 @@ $: ({ data: mockedUserDeploymentCredentials } = $mockedUserDeploymentCredentialsQuery); - // Depending on the current page, we use the results from the cookie query or the token query - $: error = ( - onMagicLinkPage ? tokenProjectError : cookieProjectError - ) as HTTPError; - $: projectData = onMagicLinkPage ? tokenProjectData : cookieProjectData; + $: ({ data: projectData, error: projectError } = $projectQuery); + + $: error = projectError as HTTPError; + $: authContext = ( mockedUserId && mockedUserDeploymentCredentials ? "mock" diff --git a/web-common/orval.config.ts b/web-common/orval.config.ts index 2b9ee856fef..37e2d16127c 100644 --- a/web-common/orval.config.ts +++ b/web-common/orval.config.ts @@ -96,6 +96,12 @@ export default defineConfig({ signal: true, }, }, + RuntimeService_IssueDevJWT: { + query: { + useQuery: true, + signal: true, + }, + }, }, }, }, diff --git a/web-common/package.json b/web-common/package.json index 1fcf4bba17a..72c90710cea 100644 --- a/web-common/package.json +++ b/web-common/package.json @@ -4,7 +4,7 @@ "scripts": { "lint": "prettier --check . && eslint .", "format": "prettier --write .", - "generate:runtime-client": "orval && tsx src/runtime-client/add-signal-argument.ts src/runtime-client/gen/query-service/query-service.ts", + "generate:runtime-client": "orval && tsx src/runtime-client/add-signal-argument.ts src/runtime-client/gen/query-service/query-service.ts src/runtime-client/gen/runtime-service/runtime-service.ts", "generate:template-schema": "ts-json-schema-generator -p src/features/templates/types.ts -t TemplateSpec -o ../runtime/compilers/rillv1/data/component-template-v1.json", "test": "vitest run", "coverage": "vitest run --coverage", diff --git a/web-common/src/features/dashboards/granular-access-policies/ViewAsButton.svelte b/web-common/src/features/dashboards/granular-access-policies/ViewAsButton.svelte index 36f9a22fb7e..b1d57a47015 100644 --- a/web-common/src/features/dashboards/granular-access-policies/ViewAsButton.svelte +++ b/web-common/src/features/dashboards/granular-access-policies/ViewAsButton.svelte @@ -1,8 +1,6 @@ - (viewAsMenuOpen = false)} - on:open={() => (viewAsMenuOpen = true)} -> - {#if $selectedMockUserStore === null} - - {:else} - { - if (viewAsMenuOpen) toggleFloatingElement(); - updateDevJWT(queryClient, null); - }} - active={viewAsMenuOpen} - > -
-
- Viewing as {$selectedMockUserStore.email} + + + {#if $selectedMockUserStore === null} +