feat(core): Add includeData parameter to GET /credentials (#12220)

Co-authored-by: r00gm <raul00gm@gmail.com>
This commit is contained in:
Danny Martini
2024-12-31 13:04:37 +01:00
committed by GitHub
parent 096329db51
commit f56ad8cf49
15 changed files with 526 additions and 66 deletions

View File

@@ -27,6 +27,6 @@
"dependencies": {
"xss": "catalog:",
"zod": "catalog:",
"zod-class": "0.0.15"
"zod-class": "0.0.16"
}
}

View File

@@ -0,0 +1,55 @@
import { CredentialsGetManyRequestQuery } from '../credentials-get-many-request.dto';
describe('CredentialsGetManyRequestQuery', () => {
describe('should pass validation', () => {
it('with empty object', () => {
const data = {};
const result = CredentialsGetManyRequestQuery.safeParse(data);
expect(result.success).toBe(true);
});
test.each([
{ field: 'includeScopes', value: 'true' },
{ field: 'includeScopes', value: 'false' },
{ field: 'includeData', value: 'true' },
{ field: 'includeData', value: 'false' },
])('with $field set to $value', ({ field, value }) => {
const data = { [field]: value };
const result = CredentialsGetManyRequestQuery.safeParse(data);
expect(result.success).toBe(true);
});
it('with both parameters set', () => {
const data = {
includeScopes: 'true',
includeData: 'true',
};
const result = CredentialsGetManyRequestQuery.safeParse(data);
expect(result.success).toBe(true);
});
});
describe('should fail validation', () => {
test.each([
{ field: 'includeScopes', value: true },
{ field: 'includeScopes', value: false },
{ field: 'includeScopes', value: 'invalid' },
{ field: 'includeData', value: true },
{ field: 'includeData', value: false },
{ field: 'includeData', value: 'invalid' },
])('with invalid value $value for $field', ({ field, value }) => {
const data = { [field]: value };
const result = CredentialsGetManyRequestQuery.safeParse(data);
expect(result.success).toBe(false);
expect(result.error?.issues[0].path[0]).toBe(field);
});
});
});

View File

@@ -0,0 +1,52 @@
import { CredentialsGetOneRequestQuery } from '../credentials-get-one-request.dto';
describe('CredentialsGetManyRequestQuery', () => {
describe('should pass validation', () => {
it('with empty object', () => {
const data = {};
const result = CredentialsGetOneRequestQuery.safeParse(data);
expect(result.success).toBe(true);
// defaults to false
expect(result.data?.includeData).toBe(false);
});
test.each([
{ field: 'includeData', value: 'true' },
{ field: 'includeData', value: 'false' },
])('with $field set to $value', ({ field, value }) => {
const data = { [field]: value };
const result = CredentialsGetOneRequestQuery.safeParse(data);
expect(result.success).toBe(true);
});
it('with both parameters set', () => {
const data = {
includeScopes: 'true',
includeData: 'true',
};
const result = CredentialsGetOneRequestQuery.safeParse(data);
expect(result.success).toBe(true);
});
});
describe('should fail validation', () => {
test.each([
{ field: 'includeData', value: true },
{ field: 'includeData', value: false },
{ field: 'includeData', value: 'invalid' },
])('with invalid value $value for $field', ({ field, value }) => {
const data = { [field]: value };
const result = CredentialsGetOneRequestQuery.safeParse(data);
expect(result.success).toBe(false);
expect(result.error?.issues[0].path[0]).toBe(field);
});
});
});

View File

@@ -0,0 +1,22 @@
import { Z } from 'zod-class';
import { booleanFromString } from '../../schemas/booleanFromString';
export class CredentialsGetManyRequestQuery extends Z.class({
/**
* Adds the `scopes` field to each credential which includes all scopes the
* requesting user has in relation to the credential, e.g.
* ['credential:read', 'credential:update']
*/
includeScopes: booleanFromString.optional(),
/**
* Adds the decrypted `data` field to each credential.
*
* It only does this for credentials for which the user has the
* `credential:update` scope.
*
* This switches `includeScopes` to true to be able to check for the scopes
*/
includeData: booleanFromString.optional(),
}) {}

View File

@@ -0,0 +1,13 @@
import { Z } from 'zod-class';
import { booleanFromString } from '../../schemas/booleanFromString';
export class CredentialsGetOneRequestQuery extends Z.class({
/**
* Adds the decrypted `data` field to each credential.
*
* It only does this for credentials for which the user has the
* `credential:update` scope.
*/
includeData: booleanFromString.optional().default('false'),
}) {}

View File

@@ -29,3 +29,5 @@ export { UserUpdateRequestDto } from './user/user-update-request.dto';
export { CommunityRegisteredRequestDto } from './license/community-registered-request.dto';
export { VariableListRequestDto } from './variables/variables-list-request.dto';
export { CredentialsGetOneRequestQuery } from './credentials/credentials-get-one-request.dto';
export { CredentialsGetManyRequestQuery } from './credentials/credentials-get-many-request.dto';

View File

@@ -0,0 +1,3 @@
import { z } from 'zod';
export const booleanFromString = z.enum(['true', 'false']).transform((value) => value === 'true');