-
Notifications
You must be signed in to change notification settings - Fork 81
Feat/generate token for client #1465
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c0b82b5
e686b3d
685e7f0
2df98e3
9a1a8f9
a7f85c4
97948cf
ef1fbee
9ce164f
5f4a60b
598d182
42eca11
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| import { ApiProperty } from '@nestjs/swagger'; | ||
| import { IsString } from 'class-validator'; | ||
|
|
||
| export class ClientTokenDto { | ||
| @ApiProperty() | ||
| @IsString({ message: 'orgId must be in string format.' }) | ||
| orgId: string; | ||
|
|
||
| @ApiProperty() | ||
| @IsString({ message: 'clientAlias must be in string format.' }) | ||
| clientAlias: string; | ||
|
|
||
| @ApiProperty() | ||
| @IsString({ message: 'clientId must be in string format.' }) | ||
| clientId: string; | ||
|
|
||
| @ApiProperty() | ||
| @IsString({ message: 'clientSecret must be in string format.' }) | ||
| clientSecret: string; | ||
|
|
||
| @ApiProperty() | ||
| @IsString({ message: 'grantType must be in string format.' }) | ||
| grantType?: string = 'client_credentials'; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| export class ClientTokenDto { | ||
| orgId: string; | ||
| clientAlias: string; | ||
| clientId: string; | ||
| clientSecret: string; | ||
| grantType?: string = 'client_credentials'; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,12 +4,27 @@ import { OrganizationService } from './organization.service'; | |||||||||||||||||||||
| import { CreateOrganizationDto } from '../dtos/create-organization.dto'; | ||||||||||||||||||||||
| import { BulkSendInvitationDto } from '../dtos/send-invitation.dto'; | ||||||||||||||||||||||
| import { UpdateInvitationDto } from '../dtos/update-invitation.dt'; | ||||||||||||||||||||||
| import { IDidList, IGetOrgById, IGetOrganization, IOrgDetails, IUpdateOrganization, Payload } from '../interfaces/organization.interface'; | ||||||||||||||||||||||
| import { IOrgCredentials, IOrganizationInvitations, IOrganization, IOrganizationDashboard, IDeleteOrganization, IOrgActivityCount } from '@credebl/common/interfaces/organization.interface'; | ||||||||||||||||||||||
| import { | ||||||||||||||||||||||
| IDidList, | ||||||||||||||||||||||
| IGetOrgById, | ||||||||||||||||||||||
| IGetOrganization, | ||||||||||||||||||||||
| IOrgDetails, | ||||||||||||||||||||||
| IUpdateOrganization, | ||||||||||||||||||||||
| Payload | ||||||||||||||||||||||
| } from '../interfaces/organization.interface'; | ||||||||||||||||||||||
| import { | ||||||||||||||||||||||
| IOrgCredentials, | ||||||||||||||||||||||
| IOrganizationInvitations, | ||||||||||||||||||||||
| IOrganization, | ||||||||||||||||||||||
| IOrganizationDashboard, | ||||||||||||||||||||||
| IDeleteOrganization, | ||||||||||||||||||||||
| IOrgActivityCount | ||||||||||||||||||||||
| } from '@credebl/common/interfaces/organization.interface'; | ||||||||||||||||||||||
| import { organisation, user } from '@prisma/client'; | ||||||||||||||||||||||
| import { IAccessTokenData } from '@credebl/common/interfaces/interface'; | ||||||||||||||||||||||
| import { IClientRoles } from '@credebl/client-registration/interfaces/client.interface'; | ||||||||||||||||||||||
| import { IOrgRoles } from 'libs/org-roles/interfaces/org-roles.interface'; | ||||||||||||||||||||||
| import { ClientTokenDto } from '../dtos/client-token.dto'; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @Controller() | ||||||||||||||||||||||
| export class OrganizationController { | ||||||||||||||||||||||
|
|
@@ -23,7 +38,9 @@ export class OrganizationController { | |||||||||||||||||||||
| */ | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'create-organization' }) | ||||||||||||||||||||||
| async createOrganization(@Body() payload: { createOrgDto: CreateOrganizationDto; userId: string, keycloakUserId: string }): Promise<organisation> { | ||||||||||||||||||||||
| async createOrganization( | ||||||||||||||||||||||
| @Body() payload: { createOrgDto: CreateOrganizationDto; userId: string; keycloakUserId: string } | ||||||||||||||||||||||
| ): Promise<organisation> { | ||||||||||||||||||||||
|
shitrerohit marked this conversation as resolved.
|
||||||||||||||||||||||
| return this.organizationService.createOrganization(payload.createOrgDto, payload.userId, payload.keycloakUserId); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -34,17 +51,19 @@ export class OrganizationController { | |||||||||||||||||||||
| */ | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'set-primary-did' }) | ||||||||||||||||||||||
| async setPrimaryDid(@Body() payload: { orgId:string, did:string, id:string}): Promise<string> { | ||||||||||||||||||||||
| async setPrimaryDid(@Body() payload: { orgId: string; did: string; id: string }): Promise<string> { | ||||||||||||||||||||||
|
shitrerohit marked this conversation as resolved.
|
||||||||||||||||||||||
| return this.organizationService.setPrimaryDid(payload.orgId, payload.did, payload.id); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /** | ||||||||||||||||||||||
| * | ||||||||||||||||||||||
| * @param payload | ||||||||||||||||||||||
| * | ||||||||||||||||||||||
| * @param payload | ||||||||||||||||||||||
| * @returns organization client credentials | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| @MessagePattern({ cmd: 'create-org-credentials' }) | ||||||||||||||||||||||
| async createOrgCredentials(@Body() payload: { orgId: string; userId: string, keycloakUserId: string }): Promise<IOrgCredentials> { | ||||||||||||||||||||||
| async createOrgCredentials( | ||||||||||||||||||||||
| @Body() payload: { orgId: string; userId: string; keycloakUserId: string } | ||||||||||||||||||||||
| ): Promise<IOrgCredentials> { | ||||||||||||||||||||||
|
shitrerohit marked this conversation as resolved.
|
||||||||||||||||||||||
| return this.organizationService.createOrgCredentials(payload.orgId, payload.userId, payload.keycloakUserId); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -55,7 +74,11 @@ export class OrganizationController { | |||||||||||||||||||||
| */ | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'update-organization' }) | ||||||||||||||||||||||
| async updateOrganization(payload: { updateOrgDto: IUpdateOrganization; userId: string, orgId: string }): Promise<organisation> { | ||||||||||||||||||||||
| async updateOrganization(payload: { | ||||||||||||||||||||||
| updateOrgDto: IUpdateOrganization; | ||||||||||||||||||||||
| userId: string; | ||||||||||||||||||||||
| orgId: string; | ||||||||||||||||||||||
| }): Promise<organisation> { | ||||||||||||||||||||||
| return this.organizationService.updateOrganization(payload.updateOrgDto, payload.userId, payload.orgId); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -65,7 +88,7 @@ export class OrganizationController { | |||||||||||||||||||||
| * @returns organization's did list | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| @MessagePattern({ cmd: 'fetch-organization-dids' }) | ||||||||||||||||||||||
| async getOrgDidList(payload: {orgId:string}): Promise<IDidList[]> { | ||||||||||||||||||||||
| async getOrgDidList(payload: { orgId: string }): Promise<IDidList[]> { | ||||||||||||||||||||||
| return this.organizationService.getOrgDidList(payload.orgId); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -75,9 +98,7 @@ export class OrganizationController { | |||||||||||||||||||||
| * @returns Get created organization details | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| @MessagePattern({ cmd: 'get-organizations' }) | ||||||||||||||||||||||
| async getOrganizations( | ||||||||||||||||||||||
| @Body() payload: { userId: string} & Payload | ||||||||||||||||||||||
| ): Promise<IGetOrganization> { | ||||||||||||||||||||||
| async getOrganizations(@Body() payload: { userId: string } & Payload): Promise<IGetOrganization> { | ||||||||||||||||||||||
| const { userId, pageNumber, pageSize, search, role } = payload; | ||||||||||||||||||||||
| return this.organizationService.getOrganizations(userId, pageNumber, pageSize, search, role); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+101
to
104
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove @Body() from @MessagePattern handler. @Body is HTTP-only; with NATS it yields undefined. Use plain param or @payload() from microservices. -async getOrganizations(@Body() payload: { userId: string } & Payload): Promise<IGetOrganization> {
+async getOrganizations(payload: { userId: string } & Payload): Promise<IGetOrganization> {📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
@@ -87,22 +108,17 @@ export class OrganizationController { | |||||||||||||||||||||
| * @returns Get created organization details | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| @MessagePattern({ cmd: 'get-organizations-count' }) | ||||||||||||||||||||||
| async countTotalOrgs( | ||||||||||||||||||||||
| @Body() payload: { userId: string} | ||||||||||||||||||||||
| ): Promise<number> { | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| async countTotalOrgs(@Body() payload: { userId: string }): Promise<number> { | ||||||||||||||||||||||
|
shitrerohit marked this conversation as resolved.
|
||||||||||||||||||||||
| const { userId } = payload; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return this.organizationService.countTotalOrgs(userId); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /** | ||||||||||||||||||||||
| * @returns Get public organization details | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| @MessagePattern({ cmd: 'get-public-organizations' }) | ||||||||||||||||||||||
| async getPublicOrganizations( | ||||||||||||||||||||||
| @Body() payload: Payload | ||||||||||||||||||||||
| ): Promise<IGetOrganization> { | ||||||||||||||||||||||
| async getPublicOrganizations(@Body() payload: Payload): Promise<IGetOrganization> { | ||||||||||||||||||||||
|
shitrerohit marked this conversation as resolved.
|
||||||||||||||||||||||
| const { pageNumber, pageSize, search } = payload; | ||||||||||||||||||||||
| return this.organizationService.getPublicOrganizations(pageNumber, pageSize, search); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
@@ -113,13 +129,13 @@ export class OrganizationController { | |||||||||||||||||||||
| * @returns Get created organization details | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| @MessagePattern({ cmd: 'get-organization-by-id' }) | ||||||||||||||||||||||
| async getOrganization(@Body() payload: { orgId: string; userId: string}): Promise<IGetOrgById> { | ||||||||||||||||||||||
| async getOrganization(@Body() payload: { orgId: string; userId: string }): Promise<IGetOrgById> { | ||||||||||||||||||||||
| return this.organizationService.getOrganization(payload.orgId); | ||||||||||||||||||||||
|
shitrerohit marked this conversation as resolved.
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
| /** | ||||||||||||||||||||||
| * @param orgSlug | ||||||||||||||||||||||
| * @returns organization details | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| /** | ||||||||||||||||||||||
| * @param orgSlug | ||||||||||||||||||||||
| * @returns organization details | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| @MessagePattern({ cmd: 'get-organization-public-profile' }) | ||||||||||||||||||||||
| async getPublicProfile(payload: { orgSlug }): Promise<IGetOrgById> { | ||||||||||||||||||||||
| return this.organizationService.getPublicProfile(payload); | ||||||||||||||||||||||
|
|
@@ -131,9 +147,7 @@ export class OrganizationController { | |||||||||||||||||||||
| * @returns Get created invitation details | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| @MessagePattern({ cmd: 'get-invitations-by-orgId' }) | ||||||||||||||||||||||
| async getInvitationsByOrgId( | ||||||||||||||||||||||
| @Body() payload: { orgId: string } & Payload | ||||||||||||||||||||||
| ): Promise<IOrganizationInvitations> { | ||||||||||||||||||||||
| async getInvitationsByOrgId(@Body() payload: { orgId: string } & Payload): Promise<IOrganizationInvitations> { | ||||||||||||||||||||||
|
shitrerohit marked this conversation as resolved.
|
||||||||||||||||||||||
| return this.organizationService.getInvitationsByOrgId( | ||||||||||||||||||||||
| payload.orgId, | ||||||||||||||||||||||
| payload.pageNumber, | ||||||||||||||||||||||
|
|
@@ -143,11 +157,11 @@ export class OrganizationController { | |||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /** | ||||||||||||||||||||||
| * @returns Get org-roles | ||||||||||||||||||||||
| * @returns Get org-roles | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'get-org-roles' }) | ||||||||||||||||||||||
| async getOrgRoles(payload: {orgId: string, user: user}): Promise<IClientRoles[]> { | ||||||||||||||||||||||
| async getOrgRoles(payload: { orgId: string; user: user }): Promise<IClientRoles[]> { | ||||||||||||||||||||||
| return this.organizationService.getOrgRoles(payload.orgId, payload.user); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -163,7 +177,7 @@ export class OrganizationController { | |||||||||||||||||||||
| */ | ||||||||||||||||||||||
| @MessagePattern({ cmd: 'send-invitation' }) | ||||||||||||||||||||||
| async createInvitation( | ||||||||||||||||||||||
| @Body() payload: { bulkInvitationDto: BulkSendInvitationDto; userId: string, userEmail: string } | ||||||||||||||||||||||
| @Body() payload: { bulkInvitationDto: BulkSendInvitationDto; userId: string; userEmail: string } | ||||||||||||||||||||||
|
shitrerohit marked this conversation as resolved.
|
||||||||||||||||||||||
| ): Promise<string> { | ||||||||||||||||||||||
| return this.organizationService.createInvitation(payload.bulkInvitationDto, payload.userId, payload.userEmail); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
@@ -198,7 +212,7 @@ export class OrganizationController { | |||||||||||||||||||||
| */ | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'update-user-roles' }) | ||||||||||||||||||||||
| async updateUserRoles(payload: { orgId: string; roleIds: string[]; userId: string}): Promise<boolean> { | ||||||||||||||||||||||
| async updateUserRoles(payload: { orgId: string; roleIds: string[]; userId: string }): Promise<boolean> { | ||||||||||||||||||||||
| return this.organizationService.updateUserRoles(payload.orgId, payload.roleIds, payload.userId); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -212,9 +226,9 @@ export class OrganizationController { | |||||||||||||||||||||
| return this.organizationService.getOrganizationActivityCount(payload.orgId, payload.userId); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /** | ||||||||||||||||||||||
| * @returns organization profile details | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| /** | ||||||||||||||||||||||
| * @returns organization profile details | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| @MessagePattern({ cmd: 'fetch-organization-profile' }) | ||||||||||||||||||||||
| async getOrgPofile(payload: { orgId: string }): Promise<organisation> { | ||||||||||||||||||||||
| return this.organizationService.getOrgPofile(payload.orgId); | ||||||||||||||||||||||
|
|
@@ -231,27 +245,27 @@ export class OrganizationController { | |||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'get-organization-details' }) | ||||||||||||||||||||||
| async getOrgData(payload: { orgId: string; }): Promise<organisation> { | ||||||||||||||||||||||
| async getOrgData(payload: { orgId: string }): Promise<organisation> { | ||||||||||||||||||||||
| return this.organizationService.getOrgDetails(payload.orgId); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'delete-organization' }) | ||||||||||||||||||||||
| async deleteOrganization(payload: { orgId: string, user: user }): Promise<IDeleteOrganization> { | ||||||||||||||||||||||
| async deleteOrganization(payload: { orgId: string; user: user }): Promise<IDeleteOrganization> { | ||||||||||||||||||||||
| return this.organizationService.deleteOrganization(payload.orgId, payload.user); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'delete-org-client-credentials' }) | ||||||||||||||||||||||
| async deleteOrganizationCredentials(payload: { orgId: string, user: user }): Promise<string> { | ||||||||||||||||||||||
| async deleteOrganizationCredentials(payload: { orgId: string; user: user }): Promise<string> { | ||||||||||||||||||||||
| return this.organizationService.deleteClientCredentials(payload.orgId, payload.user); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'delete-organization-invitation' }) | ||||||||||||||||||||||
| async deleteOrganizationInvitation(payload: { orgId: string; invitationId: string; }): Promise<boolean> { | ||||||||||||||||||||||
| async deleteOrganizationInvitation(payload: { orgId: string; invitationId: string }): Promise<boolean> { | ||||||||||||||||||||||
| return this.organizationService.deleteOrganizationInvitation(payload.orgId, payload.invitationId); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'authenticate-client-credentials' }) | ||||||||||||||||||||||
| async clientLoginCredentails(payload: { clientId: string; clientSecret: string;}): Promise<IAccessTokenData> { | ||||||||||||||||||||||
| async clientLoginCredentails(payload: { clientId: string; clientSecret: string }): Promise<IAccessTokenData> { | ||||||||||||||||||||||
| return this.organizationService.clientLoginCredentails(payload); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -261,12 +275,12 @@ export class OrganizationController { | |||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'get-agent-type-by-org-agent-type-id' }) | ||||||||||||||||||||||
| async getAgentTypeByAgentTypeId(payload: {orgAgentTypeId: string}): Promise<string> { | ||||||||||||||||||||||
| async getAgentTypeByAgentTypeId(payload: { orgAgentTypeId: string }): Promise<string> { | ||||||||||||||||||||||
| return this.organizationService.getAgentTypeByAgentTypeId(payload.orgAgentTypeId); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'get-org-roles-details' }) | ||||||||||||||||||||||
| async getOrgRolesDetails(payload: {roleName: string}): Promise<object> { | ||||||||||||||||||||||
| async getOrgRolesDetails(payload: { roleName: string }): Promise<object> { | ||||||||||||||||||||||
| return this.organizationService.getOrgRolesDetails(payload.roleName); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -286,7 +300,12 @@ export class OrganizationController { | |||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'get-org-agents-and-user-roles' }) | ||||||||||||||||||||||
| async getOrgAgentDetailsForEcosystem(payload: {orgIds: string[], search: string}): Promise<IOrgDetails> { | ||||||||||||||||||||||
| async getOrgAgentDetailsForEcosystem(payload: { orgIds: string[]; search: string }): Promise<IOrgDetails> { | ||||||||||||||||||||||
| return this.organizationService.getOrgAgentDetailsForEcosystem(payload); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @MessagePattern({ cmd: 'generate-client-api-token' }) | ||||||||||||||||||||||
| async generateClientApiToken(payload: ClientTokenDto): Promise<{ token: string }> { | ||||||||||||||||||||||
| return this.organizationService.generateClientApiToken(payload); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+307
to
+310
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainDo not accept or forward admin secrets; use alias-only request and fetch creds server-side. The DTO currently includes clientId/clientSecret (via import). Secrets should not traverse the message bus. Accept orgId + clientAlias only; resolve clientId/secret inside the organization service. -@MessagePattern({ cmd: 'generate-client-api-token' })
-async generateClientApiToken(payload: ClientTokenDto): Promise<{ token: string }> {
- return this.organizationService.generateClientApiToken(payload);
-}
+@MessagePattern({ cmd: 'generate-client-api-token' })
+async generateClientApiToken(payload: { orgId: string; clientAlias: string; grantType?: 'client_credentials' }): Promise<{ token: string }> {
+ return this.organizationService.generateClientApiToken(payload);
+}🏁 Script executed: #!/bin/bash
# Ensure no @Body() remains in @MessagePattern handlers
rg -n "@MessagePattern" -n -C1 apps/organization/src/organization.controller.ts | rg -n "@Body\\("Length of output: 712 🏁 Script executed: #!/bin/bash
# Display context around generateClientApiToken in controller
sed -n '250,330p' apps/organization/src/organization.controller.ts
# Locate ClientTokenDto definition and inspect fields
rg -n "export class ClientTokenDto" -g "apps/organization/src/**/*.dto.ts" -C3Length of output: 2865 🏁 Script executed: #!/bin/bash
# Locate ClientTokenDto definition in repository
rg -n "class ClientTokenDto" -C5 .
rg -n "interface ClientTokenDto" -C5 .Length of output: 1733 Remove client secrets from the message bus and strip
@MessagePattern({ cmd: 'generate-client-api-token' })
-async generateClientApiToken(payload: ClientTokenDto): Promise<{ token: string }> {
+async generateClientApiToken(payload: { orgId: string; clientAlias: string; grantType?: 'client_credentials' }): Promise<{ token: string }> {
return this.organizationService.generateClientApiToken(payload);
}
📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove secret-bearing fields from the gateway DTO.
This DTO exposes
clientIdandclientSecretto external callers, meaning admin credentials now traverse user payloads, logs, traces, and NATS messages. That is a critical secret-handling flaw—attackers can supply arbitrary secrets or exfiltrate the real ones. Fetch the admin client credentials server-side (e.g., byclientAliasfrom a secure store) and drop these fields from the public contract. Return a 400 if clients include them.🤖 Prompt for AI Agents