Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ Use these annotations to allow the tool to authenticate automatically:
- `x-act-auth-field`: Defines the relevant fields for authentication and must be set to one of the following valid types:

| Type | Description |
|--------------|------------------------------------------------------------------------------------------------------|
| ------------ | ---------------------------------------------------------------------------------------------------- |
| `identifier` | Specifies the field in the request body that contains the user identifier (e.g., username or email). |
| `password` | Defines the field in the request body that holds the user's password. |
| `token` | Specifies the field in the response body where the authentication token is returned. |
Expand Down
46 changes: 46 additions & 0 deletions demo-application/public/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,52 @@ paths:
security:
- bearerHttpAuthentication: [ ]
- cookieAuthentication: [ ]
/admin/usersByQueryString:
get:
summary: Einzelner Benutzer
description: Gibt einen spezifischen Benutzer anhand der ID zurück.
parameters:
- name: id
in: query
required: true
description: User-ID
schema:
type: integer
example: 1
x-act:
resource-name: User
resource-access: read
responses:
'200':
description: Erfolgreiche Antwort
content:
application/json:
schema:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: Max Mustermann
email:
type: string
example: max@beispiel.de
'404':
description: Benutzer nicht gefunden
content:
application/json:
schema:
type: object
properties:
error:
type: string
example: Benutzer nicht gefunden.
security:
- cookieAuthentication: [ ]
- bearerHttpAuthentication: [ ]
- basicHttpAuthentication: [ ]
/admin/users/{id}:
get:
summary: Einzelner Benutzer
Expand Down
6 changes: 6 additions & 0 deletions demo-application/start/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ router
router.get('/users/:id', async ({ params }) => {
return User.findOrFail(params.id)
})

router.get('/usersByQueryString', async ({ request }) => {
const { id } = request.qs()

return User.findOrFail(id)
})
})
.use(middlewareAuth)
.prefix('/admin')
Expand Down
15 changes: 8 additions & 7 deletions src/core/parsers/openapi-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@
const securitySchemes = operation.getSecurityWithTypes();

const hasCombinedSecuritySchemes = securitySchemes.some(
(securitySchemeItem) => securitySchemeItem.length > 1,
(securitySchemeItem) =>
Array.isArray(securitySchemeItem) && securitySchemeItem.length > 1,
);

if (hasCombinedSecuritySchemes) {
Expand Down Expand Up @@ -444,7 +445,7 @@
}

if (
authenticatorType === AuthenticatorType.API_KEY_COOKIE &&

Check warning on line 448 in src/core/parsers/openapi-parser.ts

View workflow job for this annotation

GitHub Actions / Run all tests

Unnecessary conditional, comparison is always true, since `AuthenticatorType.API_KEY_COOKIE === AuthenticatorType.API_KEY_COOKIE` is true
"name" in securityScheme
) {
const authResponseParameterDescription = {
Expand All @@ -455,7 +456,7 @@
// todo: check if parameterLocation is of type ParameterLocation
if (
!authResponseParameterDescription.parameterName ||
!authResponseParameterDescription.parameterLocation

Check warning on line 459 in src/core/parsers/openapi-parser.ts

View workflow job for this annotation

GitHub Actions / Run all tests

Unnecessary conditional, value is always falsy
) {
throw new Error(
"Could not find parameter name (name) or parameter location (in) for Cookie Authentication",
Expand Down Expand Up @@ -525,7 +526,7 @@
httpMethod as HttpMethods,
);

if (!operation) {

Check warning on line 529 in src/core/parsers/openapi-parser.ts

View workflow job for this annotation

GitHub Actions / Run all tests

Unnecessary conditional, value is always falsy
throw new Error("Operation not found");
}

Expand Down Expand Up @@ -576,19 +577,19 @@
}

/**
* Expands a URL template with the given parameters
* Expands a URL template with the given path parameters
*
* @param urlTemplateString The URL template as string to expand
* @param parameters The parameters to expand the URL template with
* @param pathParameters The path parameters to expand the URL template with
* @returns The expanded path or URL as string
*/
static expandUrlTemplate(
urlTemplateString: string,
parameters: Record<string | number | symbol, string | number>,
pathParameters: Record<string | number | symbol, string | number>,
): string {
const urlTemplate = parseTemplate(urlTemplateString);

return urlTemplate.expand(parameters);
return urlTemplate.expand(pathParameters);
}

static combineUrl(baseUrl: string, path: string) {
Expand All @@ -597,8 +598,8 @@
);
}

constructFullApiUrl(url: string) {
return OpenAPIParser.combineUrl(this.apiBaseUrl, url);
constructFullApiUrl(path: string) {
return OpenAPIParser.combineUrl(this.apiBaseUrl, path);
}

static pathContainsParameter(path: string, parameterName: string) {
Expand Down
47 changes: 31 additions & 16 deletions src/core/tests/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
* authenticate. See
* {@link https://github.com/sindresorhus/got/blob/main/documentation/8-errors.md list of errors}
*/
export async function performRequest({

Check warning on line 42 in src/core/tests/test-utils.ts

View workflow job for this annotation

GitHub Actions / Run all tests

Expected a function expression

Check warning on line 42 in src/core/tests/test-utils.ts

View workflow job for this annotation

GitHub Actions / Run all tests

Use const or class constructors instead of named functions
route,
requestBody,
authenticator,
Expand Down Expand Up @@ -138,7 +138,7 @@
* Creates the request data for an individual test combination by returning the
* route to use and optionally the request body.
*/
export function createRequestData({

Check warning on line 141 in src/core/tests/test-utils.ts

View workflow job for this annotation

GitHub Actions / Run all tests

Expected a function expression
path,
method,
currentResource,
Expand All @@ -157,26 +157,41 @@
// resourceIdentifier can be undefined when resource access is create for instance
// or when access for all resources of a type is described
let requestBody: RequestBody;
let processedPath = path;
const queryParameters = new URLSearchParams();

const expandedPath =
resourceIdentifier === undefined ||
currentResource.parameterName === undefined ||
currentResource.parameterLocation !== "path"
? path
: OpenAPIParser.expandUrlTemplate(path, {
if (
currentResource.parameterName !== undefined &&
resourceIdentifier !== undefined
) {
switch (currentResource.parameterLocation) {
case "path": {
processedPath = OpenAPIParser.expandUrlTemplate(path, {
[currentResource.parameterName]: resourceIdentifier,
});
break;
}
case "query": {
queryParameters.set(
currentResource.parameterName,
resourceIdentifier.toString(),
);
break;
}
case "body": {
// todo: this only works for params on the top level of the request body
requestBody = {
[currentResource.parameterName]: resourceIdentifier,
}); // todo: for multiple resources and therefore parameters, multiple keys in object -> dynamic mapping required
};
break;
}
}
}

const url = openApiParser.constructFullApiUrl(expandedPath);
const url = openApiParser.constructFullApiUrl(processedPath);

// todo: this only works for params on the top level of the request body
if (
currentResource.parameterLocation === "body" &&
currentResource.parameterName !== undefined
) {
requestBody = {
[currentResource.parameterName]: resourceIdentifier,
};
if (queryParameters.size > 0) {
url.search = queryParameters.toString();
}

return {
Expand Down
Loading