From 01d8f9bfd28d485039c4ffefbf622406b0f14ac4 Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Wed, 13 Nov 2024 14:37:34 -0800 Subject: [PATCH 1/3] feat: add gnap error response schema to spec --- openapi/auth-server.yaml | 76 ++++++++++++++ .../openapi/generated/auth-server-types.ts | 98 ++++++++++++++++--- 2 files changed, 160 insertions(+), 14 deletions(-) diff --git a/openapi/auth-server.yaml b/openapi/auth-server.yaml index eb30e628..c39660d6 100644 --- a/openapi/auth-server.yaml +++ b/openapi/auth-server.yaml @@ -74,10 +74,22 @@ paths: uri: 'https://auth.rafiki.money/continue/4CF492MLVMSW9MKMXKHQ' '400': description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' '401': description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' '500': description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' requestBody: content: application/json: @@ -198,10 +210,22 @@ paths: wait: 30 '400': description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' '401': description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' '404': description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' requestBody: content: application/json: @@ -228,10 +252,22 @@ paths: description: No Content '400': description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' '401': description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' '404': description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' description: Cancel a grant request or delete a grant client side. tags: - grant @@ -279,10 +315,22 @@ paths: assetScale: 2 '400': description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' '401': description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' '404': description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' description: Management endpoint to rotate access token. tags: - token @@ -295,8 +343,16 @@ paths: description: No Content '400': description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' '401': description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/gnap-error' tags: - token components: @@ -532,6 +588,26 @@ components: - debitAmount - required: - receiveAmount + gnap-error: + type: object + properties: + error: + type: object + properties: + description: + type: string + code: + type: string + enum: + - invalid_request + - invalid_client + - invalid_interaction + - invalid_rotation + - invalid_continuation + - user_denied + - request_denied + - unknown_interaction + - too_fast securitySchemes: GNAP: name: Authorization diff --git a/packages/open-payments/src/openapi/generated/auth-server-types.ts b/packages/open-payments/src/openapi/generated/auth-server-types.ts index 00c0cf44..b0c33937 100644 --- a/packages/open-payments/src/openapi/generated/auth-server-types.ts +++ b/packages/open-payments/src/openapi/generated/auth-server-types.ts @@ -172,6 +172,20 @@ export interface components { receiveAmount?: external["schemas.yaml"]["components"]["schemas"]["amount"]; interval?: components["schemas"]["interval"]; }; + "gnap-error": { + error?: { + description?: string; + code?: + | "invalid_request" + | "invalid_client" + | "invalid_interaction" + | "invalid_rotation" + | "invalid_continuation" + | "user_denied" + | "request_denied" + | "unknown_interaction - too_fast"; + }; + }; }; } @@ -195,11 +209,23 @@ export interface operations { }; }; /** Bad Request */ - 400: unknown; + 400: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; /** Unauthorized */ - 401: unknown; + 401: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; /** Internal Server Error */ - 500: unknown; + 500: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; }; requestBody: { content: { @@ -231,11 +257,23 @@ export interface operations { }; }; /** Bad Request */ - 400: unknown; + 400: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; /** Unauthorized */ - 401: unknown; + 401: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; /** Not Found */ - 404: unknown; + 404: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; }; requestBody: { content: { @@ -260,11 +298,23 @@ export interface operations { /** No Content */ 204: never; /** Bad Request */ - 400: unknown; + 400: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; /** Unauthorized */ - 401: unknown; + 401: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; /** Not Found */ - 404: unknown; + 404: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; }; }; /** Management endpoint to rotate access token. */ @@ -284,11 +334,23 @@ export interface operations { }; }; /** Bad Request */ - 400: unknown; + 400: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; /** Unauthorized */ - 401: unknown; + 401: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; /** Not Found */ - 404: unknown; + 404: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; }; }; /** Management endpoint to revoke access token. */ @@ -302,9 +364,17 @@ export interface operations { /** No Content */ 204: never; /** Bad Request */ - 400: unknown; + 400: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; /** Unauthorized */ - 401: unknown; + 401: { + content: { + "application/json": components["schemas"]["gnap-error"]; + }; + }; }; }; } From 08b1293619258368aa2f8c7ebdecb640bdaa8537 Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Fri, 15 Nov 2024 11:31:51 -0800 Subject: [PATCH 2/3] feat: individual error objects for gnap errors --- openapi/auth-server.yaml | 126 +++++++++++++----- .../openapi/generated/auth-server-types.ts | 100 +++++++++----- 2 files changed, 162 insertions(+), 64 deletions(-) diff --git a/openapi/auth-server.yaml b/openapi/auth-server.yaml index c39660d6..5a908924 100644 --- a/openapi/auth-server.yaml +++ b/openapi/auth-server.yaml @@ -77,19 +77,21 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/gnap-error' + oneOf: + - $ref: '#/components/schemas/error-invalid-request' + - $ref: '#/components/schemas/error-invalid-client' '401': description: Unauthorized content: application/json: schema: - $ref: '#/components/schemas/gnap-error' + $ref: '#/components/schemas/error-invalid-client' '500': description: Internal Server Error content: application/json: schema: - $ref: '#/components/schemas/gnap-error' + $ref: '#/components/schemas/error-request-denied' requestBody: content: application/json: @@ -213,19 +215,26 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/gnap-error' + oneOf: + - $ref: '#/components/schemas/error-too-fast' + - $ref: '#/components/schemas/error-invalid-client' '401': description: Unauthorized content: application/json: schema: - $ref: '#/components/schemas/gnap-error' + oneOf: + - $ref: '#/components/schemas/error-invalid-client' + - $ref: '#/components/schemas/error-invalid-continuation' + - $ref: '#/components/schemas/error-request-denied' '404': description: Not Found content: application/json: schema: - $ref: '#/components/schemas/gnap-error' + oneOf: + - $ref: '#/components/schemas/error-invalid-continuation' + - $ref: '#/components/schemas/error-invalid-request' requestBody: content: application/json: @@ -250,24 +259,21 @@ paths: responses: '204': description: No Content - '400': - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/gnap-error' '401': description: Unauthorized content: application/json: schema: - $ref: '#/components/schemas/gnap-error' + oneOf: + - $ref: '#/components/schemas/error-invalid-client' + - $ref: '#/components/schemas/error-invalid-continuation' + - $ref: '#/components/schemas/error-invalid-request' '404': description: Not Found content: application/json: schema: - $ref: '#/components/schemas/gnap-error' + $ref: '#/components/schemas/error-invalid-request' description: Cancel a grant request or delete a grant client side. tags: - grant @@ -318,19 +324,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/gnap-error' + $ref: '#/components/schemas/error-invalid-rotation' '401': description: Unauthorized content: application/json: schema: - $ref: '#/components/schemas/gnap-error' + $ref: '#/components/schemas/error-invalid-client' '404': description: Not Found content: application/json: schema: - $ref: '#/components/schemas/gnap-error' + $ref: '#/components/schemas/error-invalid-rotation' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/error-request-denied' description: Management endpoint to rotate access token. tags: - token @@ -341,18 +353,18 @@ paths: responses: '204': description: No Content - '400': - description: Bad Request + '401': + description: Unauthorized content: application/json: schema: - $ref: '#/components/schemas/gnap-error' - '401': - description: Unauthorized + $ref: '#/components/schemas/error-invalid-client' + '500': + description: Internal Server Error content: application/json: schema: - $ref: '#/components/schemas/gnap-error' + $ref: '#/components/schemas/error-request-denied' tags: - token components: @@ -588,7 +600,7 @@ components: - debitAmount - required: - receiveAmount - gnap-error: + error-invalid-client: type: object properties: error: @@ -599,15 +611,67 @@ components: code: type: string enum: - - invalid_request - invalid_client - - invalid_interaction - - invalid_rotation - - invalid_continuation - - user_denied + error-invalid-request: + type: object + properties: + error: + type: object + properties: + description: + type: string + code: + type: string + enum: + - invalid_request + error-request-denied: + type: object + properties: + error: + type: object + properties: + description: + type: string + code: + type: string + enum: - request_denied - - unknown_interaction - - too_fast + error-too-fast: + type: object + properties: + error: + type: object + properties: + description: + type: string + code: + type: string + enum: + - too_fast + error-invalid-continuation: + type: object + properties: + error: + type: object + properties: + description: + type: string + code: + type: string + enum: + - invalid_continuation + error-invalid-rotation: + type: object + properties: + error: + type: object + properties: + description: + type: string + code: + type: string + enum: + - invalid_rotation securitySchemes: GNAP: name: Authorization diff --git a/packages/open-payments/src/openapi/generated/auth-server-types.ts b/packages/open-payments/src/openapi/generated/auth-server-types.ts index b0c33937..64d7b757 100644 --- a/packages/open-payments/src/openapi/generated/auth-server-types.ts +++ b/packages/open-payments/src/openapi/generated/auth-server-types.ts @@ -172,18 +172,40 @@ export interface components { receiveAmount?: external["schemas.yaml"]["components"]["schemas"]["amount"]; interval?: components["schemas"]["interval"]; }; - "gnap-error": { + "error-invalid-client": { error?: { description?: string; - code?: - | "invalid_request" - | "invalid_client" - | "invalid_interaction" - | "invalid_rotation" - | "invalid_continuation" - | "user_denied" - | "request_denied" - | "unknown_interaction - too_fast"; + code?: "invalid_client"; + }; + }; + "error-invalid-request": { + error?: { + description?: string; + code?: "invalid_request"; + }; + }; + "error-request-denied": { + error?: { + description?: string; + code?: "request_denied"; + }; + }; + "error-too-fast": { + error?: { + description?: string; + code?: "too_fast"; + }; + }; + "error-invalid-continuation": { + error?: { + description?: string; + code?: "invalid_continuation"; + }; + }; + "error-invalid-rotation": { + error?: { + description?: string; + code?: "invalid_rotation"; }; }; }; @@ -211,19 +233,21 @@ export interface operations { /** Bad Request */ 400: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": + | components["schemas"]["error-invalid-request"] + | components["schemas"]["error-invalid-client"]; }; }; /** Unauthorized */ 401: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": components["schemas"]["error-invalid-client"]; }; }; /** Internal Server Error */ 500: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": components["schemas"]["error-request-denied"]; }; }; }; @@ -259,19 +283,26 @@ export interface operations { /** Bad Request */ 400: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": + | components["schemas"]["error-too-fast"] + | components["schemas"]["error-invalid-client"]; }; }; /** Unauthorized */ 401: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": + | components["schemas"]["error-invalid-client"] + | components["schemas"]["error-invalid-continuation"] + | components["schemas"]["error-request-denied"]; }; }; /** Not Found */ 404: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": + | components["schemas"]["error-invalid-continuation"] + | components["schemas"]["error-invalid-request"]; }; }; }; @@ -297,22 +328,19 @@ export interface operations { responses: { /** No Content */ 204: never; - /** Bad Request */ - 400: { - content: { - "application/json": components["schemas"]["gnap-error"]; - }; - }; /** Unauthorized */ 401: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": + | components["schemas"]["error-invalid-client"] + | components["schemas"]["error-invalid-continuation"] + | components["schemas"]["error-invalid-request"]; }; }; /** Not Found */ 404: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": components["schemas"]["error-invalid-request"]; }; }; }; @@ -336,19 +364,25 @@ export interface operations { /** Bad Request */ 400: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": components["schemas"]["error-invalid-rotation"]; }; }; /** Unauthorized */ 401: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": components["schemas"]["error-invalid-client"]; }; }; /** Not Found */ 404: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": components["schemas"]["error-invalid-rotation"]; + }; + }; + /** Internal Server Error */ + 500: { + content: { + "application/json": components["schemas"]["error-request-denied"]; }; }; }; @@ -363,16 +397,16 @@ export interface operations { responses: { /** No Content */ 204: never; - /** Bad Request */ - 400: { + /** Unauthorized */ + 401: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": components["schemas"]["error-invalid-client"]; }; }; - /** Unauthorized */ - 401: { + /** Internal Server Error */ + 500: { content: { - "application/json": components["schemas"]["gnap-error"]; + "application/json": components["schemas"]["error-request-denied"]; }; }; }; From e505fc36933f931f2ad200d4314bfe04496ca175 Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Tue, 19 Nov 2024 15:24:03 -0800 Subject: [PATCH 3/3] feat: changeset --- .changeset/plenty-cooks-mix.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/plenty-cooks-mix.md diff --git a/.changeset/plenty-cooks-mix.md b/.changeset/plenty-cooks-mix.md new file mode 100644 index 00000000..ce74fcc9 --- /dev/null +++ b/.changeset/plenty-cooks-mix.md @@ -0,0 +1,5 @@ +--- +'@interledger/open-payments': minor +--- + +Added GNAP error models to auth server responses.