Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0397e9d1cb
|
||
|
|
51c38739f7
|
||
|
|
f87f854417
|
||
|
|
902b0a2dfa
|
||
|
|
703859349c
|
||
|
|
2e915e18e5
|
||
|
|
f5e87ca682 | ||
|
|
3a855384a0
|
||
|
|
8ca3fd72e5
|
||
|
|
05d0383066
|
||
|
|
01dde6eded
|
||
|
|
f0d6be2420
|
||
|
|
abbadd628a
|
||
|
|
fbd6bdedcd
|
||
|
|
1aee6cb0c5 | ||
|
|
ca309f22d2 | ||
|
|
09706fc1c5 | ||
|
|
a998995a3c |
No files matched your search
@@ -1,12 +1,12 @@
|
|||||||
version: 2.1
|
version: 2.1
|
||||||
setup: true
|
setup: true
|
||||||
orbs:
|
orbs:
|
||||||
qqq-orb: kingsrook/qqq-orb@0.7.15
|
qqq-orb: kingsrook/qqq-orb@0.8
|
||||||
workflows:
|
workflows:
|
||||||
setup:
|
setup:
|
||||||
jobs:
|
jobs:
|
||||||
- qqq-orb/generate_pipeline:
|
- qqq-orb/generate_pipeline:
|
||||||
orb_version: 0.7.15
|
orb_version: '0.8'
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
ignore: automation/qbit-rc-pending
|
ignore: automation/qbit-rc-pending
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
name: build
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
jobs:
|
||||||
|
maven:
|
||||||
|
uses: self:KofTwentyTwo/ci-workflows/.gitea/workflows/maven.yaml@v1
|
||||||
|
secrets: inherit
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
profile: qbit
|
profile: qbit
|
||||||
orb_version: 0.7.15
|
orb_version: '0.8'
|
||||||
default_branch: develop
|
default_branch: develop
|
||||||
java_version: '21'
|
java_version: '21'
|
||||||
browsers: true
|
browsers: true
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
<qqq.version>4.1.0-RC.26</qqq.version> <!-- feeds qbit-build-parent's qqq-bom-pom import -->
|
||||||
<revision>0.1.0-SNAPSHOT</revision>
|
<revision>0.1.0-SNAPSHOT</revision>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
@@ -29,7 +30,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.kingsrook</groupId>
|
<groupId>com.kingsrook</groupId>
|
||||||
<artifactId>qbit-build-parent</artifactId>
|
<artifactId>qbit-build-parent</artifactId>
|
||||||
<version>2.0.0</version>
|
<version>2.2.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.kingsrook.qbits</groupId>
|
<groupId>com.kingsrook.qbits</groupId>
|
||||||
@@ -246,7 +247,7 @@
|
|||||||
<activeByDefault>true</activeByDefault>
|
<activeByDefault>true</activeByDefault>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<qqq.snapshot.version>4.1.0-RC.11</qqq.snapshot.version>
|
<qqq.snapshot.version>4.1.0-RC.26</qqq.snapshot.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|||||||
@@ -1,5 +1,44 @@
|
|||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
|
BasicErrorResponseV1:
|
||||||
|
description: "The error body of every UI API operation (core and extensions)."
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
description: "The error message (the same as message; kept for clients of\
|
||||||
|
\ UI API 1.0 to 1.5)."
|
||||||
|
type: "string"
|
||||||
|
code:
|
||||||
|
description: "A stable, machine-readable code. Well-known values: BAD_REQUEST\
|
||||||
|
\ (400), UNAUTHENTICATED (401),\nPERMISSION_DENIED (403), NOT_FOUND (404),\
|
||||||
|
\ CONFLICT (409), RATE_LIMITED (429), INTERNAL_ERROR (500),\nERROR (other).\
|
||||||
|
\ Extensions may add codes; treat an unknown code by the HTTP status.\
|
||||||
|
\ Since 1.6.0."
|
||||||
|
type: "string"
|
||||||
|
message:
|
||||||
|
description: "A message to show the user. Since 1.6.0."
|
||||||
|
type: "string"
|
||||||
|
fieldErrors:
|
||||||
|
description: "Errors about particular request fields, when known. Since\
|
||||||
|
\ 1.6.0."
|
||||||
|
items:
|
||||||
|
properties:
|
||||||
|
field:
|
||||||
|
description: "The field (or parameter) name."
|
||||||
|
type: "string"
|
||||||
|
message:
|
||||||
|
description: "The error about that field."
|
||||||
|
type: "string"
|
||||||
|
code:
|
||||||
|
description: "An optional machine-readable code, e.g. REQUIRED, TOO_LONG,\
|
||||||
|
\ PATTERN."
|
||||||
|
type: "string"
|
||||||
|
type: "object"
|
||||||
|
type: "array"
|
||||||
|
traceId:
|
||||||
|
description: "Identifies this request in the server logs (also the X-QQQ-Trace-Id\
|
||||||
|
\ response header); quote it when reporting a problem. Since 1.6.0."
|
||||||
|
type: "string"
|
||||||
|
type: "object"
|
||||||
QaCaptureCapabilityV1:
|
QaCaptureCapabilityV1:
|
||||||
description: "What QA capture means for the signed-in user. Clients that see\
|
description: "What QA capture means for the signed-in user. Clients that see\
|
||||||
\ enabled=false do nothing else."
|
\ enabled=false do nothing else."
|
||||||
@@ -237,9 +276,42 @@ components:
|
|||||||
type: "object"
|
type: "object"
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
sessionUuidCookie:
|
sessionUuidCookie:
|
||||||
|
description: "The session cookie set by POST /qqq/v1/manageSession (web clients)."
|
||||||
in: "cookie"
|
in: "cookie"
|
||||||
name: "sessionUUID"
|
name: "sessionUUID"
|
||||||
type: "apiKey"
|
type: "apiKey"
|
||||||
|
bearerAuth:
|
||||||
|
bearerFormat: "JWT or session UUID"
|
||||||
|
description: "`Authorization: Bearer <token>`, where the token is either\n-\
|
||||||
|
\ an OAuth2 access token (a signed JWT) issued by the app's identity provider\
|
||||||
|
\ to the app's client,\n or to its native client (`values.nativeClientId`\
|
||||||
|
\ in GET /qqq/v1/metaData/authentication), for\n example from the device-authorization\
|
||||||
|
\ grant or auth-code + PKCE. It is verified against the\n provider's keys\
|
||||||
|
\ (issuer, audience, expiry, signature) and gives the same user and permissions\n\
|
||||||
|
\ as signing in on the web. When it expires (401), refresh it at the provider\
|
||||||
|
\ and retry; or\n- a session UUID returned by POST /qqq/v1/manageSession,\
|
||||||
|
\ which the server keeps refreshed."
|
||||||
|
scheme: "bearer"
|
||||||
|
type: "http"
|
||||||
|
oauth2:
|
||||||
|
description: "The app's OAuth2 / OpenID Connect provider. The real endpoints\
|
||||||
|
\ come from the provider's discovery\ndocument: `{values.baseUrl}.well-known/openid-configuration`,\
|
||||||
|
\ with values from\nGET /qqq/v1/metaData/authentication. Native clients use\
|
||||||
|
\ `values.nativeClientId` (a public client)\nwith auth-code + PKCE (loopback\
|
||||||
|
\ or custom-scheme redirect URI registered at the provider) or the\ndevice-authorization\
|
||||||
|
\ grant (`device_authorization_endpoint`, RFC 8628), then send the access\
|
||||||
|
\ token\nas `Authorization: Bearer`."
|
||||||
|
flows:
|
||||||
|
authorizationCode:
|
||||||
|
authorizationUrl: "/authorize"
|
||||||
|
scopes:
|
||||||
|
email: "Email address"
|
||||||
|
offline_access: "A refresh token, to renew the access token without signing\
|
||||||
|
\ in again"
|
||||||
|
openid: "OpenID Connect sign-in"
|
||||||
|
profile: "Name, username and groups (permissions come from the groups)"
|
||||||
|
tokenUrl: "/token"
|
||||||
|
type: "oauth2"
|
||||||
info:
|
info:
|
||||||
contact:
|
contact:
|
||||||
email: "contact@kingsrook.com"
|
email: "contact@kingsrook.com"
|
||||||
@@ -280,10 +352,37 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/QaCaptureCapabilityV1"
|
$ref: "#/components/schemas/QaCaptureCapabilityV1"
|
||||||
description: "Successful Response"
|
description: "Successful Response"
|
||||||
|
404:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/BasicErrorResponseV1"
|
||||||
|
description: "Not found, or not visible to this user (code NOT_FOUND)."
|
||||||
|
409:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/BasicErrorResponseV1"
|
||||||
|
description: "Conflict with the current state, e.g. an edit conflict or\
|
||||||
|
\ an invalid transition (code CONFLICT)."
|
||||||
|
429:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/BasicErrorResponseV1"
|
||||||
|
description: "Too many requests (code RATE_LIMITED); retry later."
|
||||||
security:
|
security:
|
||||||
- sessionUuidCookie:
|
- sessionUuidCookie:
|
||||||
- "N/A"
|
- "N/A"
|
||||||
|
- bearerAuth:
|
||||||
|
- "N/A"
|
||||||
|
- oauth2:
|
||||||
|
- "openid"
|
||||||
|
- "profile"
|
||||||
|
- "email"
|
||||||
summary: "Read the QA capture capability"
|
summary: "Read the QA capture capability"
|
||||||
|
tags:
|
||||||
|
- "qa-capture"
|
||||||
/qqq/v1/qbit/qa-capture/report:
|
/qqq/v1/qbit/qa-capture/report:
|
||||||
post:
|
post:
|
||||||
description: "Stores the report (page, app, table, record, process, recent request\
|
description: "Stores the report (page, app, table, record, process, recent request\
|
||||||
@@ -322,7 +421,40 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/QaCaptureReportResultV1"
|
$ref: "#/components/schemas/QaCaptureReportResultV1"
|
||||||
description: "Successful Response"
|
description: "Successful Response"
|
||||||
|
404:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/BasicErrorResponseV1"
|
||||||
|
description: "Not found, or not visible to this user (code NOT_FOUND)."
|
||||||
|
409:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/BasicErrorResponseV1"
|
||||||
|
description: "Conflict with the current state, e.g. an edit conflict or\
|
||||||
|
\ an invalid transition (code CONFLICT)."
|
||||||
|
429:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/BasicErrorResponseV1"
|
||||||
|
description: "Too many requests (code RATE_LIMITED); retry later."
|
||||||
security:
|
security:
|
||||||
- sessionUuidCookie:
|
- sessionUuidCookie:
|
||||||
- "N/A"
|
- "N/A"
|
||||||
|
- bearerAuth:
|
||||||
|
- "N/A"
|
||||||
|
- oauth2:
|
||||||
|
- "openid"
|
||||||
|
- "profile"
|
||||||
|
- "email"
|
||||||
summary: "Create a QA report"
|
summary: "Create a QA report"
|
||||||
|
tags:
|
||||||
|
- "qa-capture"
|
||||||
|
servers:
|
||||||
|
- description: "The QQQ server that serves this document (paths include /qqq/v1)."
|
||||||
|
url: "/"
|
||||||
|
tags:
|
||||||
|
- description: "Operations of the qa-capture extension."
|
||||||
|
name: "qa-capture"
|
||||||
@@ -58,7 +58,7 @@ class QaCaptureApiContractTest extends BaseQaCaptureTest
|
|||||||
"./mvnw -Dtest=QaCaptureApiContractTest -Dqacapture.openapi.update=true test")).isEmpty();
|
"./mvnw -Dtest=QaCaptureApiContractTest -Dqacapture.openapi.update=true test")).isEmpty();
|
||||||
|
|
||||||
var model = version.generateExtensionOpenAPIModel("qqq", extension);
|
var model = version.generateExtensionOpenAPIModel("qqq", extension);
|
||||||
assertThat(model.getComponents().getSchemas().keySet()).allMatch(name -> name.startsWith("QaCapture"));
|
assertThat(model.getComponents().getSchemas().keySet()).allMatch(name -> name.startsWith("QaCapture") || name.equals("BasicErrorResponseV1"));
|
||||||
assertThat(model.getPaths().keySet()).containsExactlyInAnyOrder("/qqq/v1/qbit/qa-capture/capability", "/qqq/v1/qbit/qa-capture/report");
|
assertThat(model.getPaths().keySet()).containsExactlyInAnyOrder("/qqq/v1/qbit/qa-capture/capability", "/qqq/v1/qbit/qa-capture/report");
|
||||||
assertThat(extension.getSemanticVersion()).isEqualTo("1.0.0");
|
assertThat(extension.getSemanticVersion()).isEqualTo("1.0.0");
|
||||||
assertThat(extension.getEffectivePathPrefix()).isEqualTo("/qbit/qa-capture");
|
assertThat(extension.getEffectivePathPrefix()).isEqualTo("/qbit/qa-capture");
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ class QaCaptureServiceTest extends BaseQaCaptureTest
|
|||||||
QaCaptureCsp.customize(headers);
|
QaCaptureCsp.customize(headers);
|
||||||
assertThat(headers.getSources("script-src")).containsExactly("'self'", "https://js.jam.dev");
|
assertThat(headers.getSources("script-src")).containsExactly("'self'", "https://js.jam.dev");
|
||||||
assertThat(headers.getSources("frame-src")).containsExactly("'self'", "https://*.jam.dev");
|
assertThat(headers.getSources("frame-src")).containsExactly("'self'", "https://*.jam.dev");
|
||||||
assertThat(headers.getSources("connect-src")).containsExactly("'self'", "https://*.jam.dev");
|
assertThat(headers.getSources("connect-src")).containsExactly("'self'", "blob:", "https://*.jam.dev");
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
// a broken database is logged and leaves the headers unchanged //
|
// a broken database is logged and leaves the headers unchanged //
|
||||||
|
|||||||
Reference in new issue
Block a user