Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
9c56609
add new method to login
ikethecoder Aug 19, 2025
7fe34e9
add new method to login
ikethecoder Aug 19, 2025
574c065
upd login method
ikethecoder Aug 19, 2025
b3f108b
new org controller
ikethecoder Aug 19, 2025
61db425
add org gateway creation
ikethecoder Aug 19, 2025
9fa1862
add missing org
ikethecoder Aug 20, 2025
e10631e
extra parameters for creating a gateway
ikethecoder Aug 20, 2025
26ecc35
org gateway creation can skip access check
ikethecoder Aug 20, 2025
8cc4aaa
upd v3 org spec
ikethecoder Aug 20, 2025
6e949c7
fix org gw creation
ikethecoder Aug 20, 2025
226fd72
make each attr an array
ikethecoder Aug 20, 2025
c43f6b8
skip org-unit if not present
ikethecoder Aug 20, 2025
c11d212
fix current namespace with org unit
ikethecoder Aug 20, 2025
7059944
fix current namespace with org unit
ikethecoder Aug 20, 2025
7f434b4
dont skip the auth check
ikethecoder Aug 20, 2025
9b6be97
list updates for sdx
ikethecoder Aug 21, 2025
0426a55
upd product controller
ikethecoder Aug 21, 2025
16d62f3
upd product controller
ikethecoder Aug 21, 2025
647d65f
fix product put
ikethecoder Aug 21, 2025
6d2dd03
upd product details
ikethecoder Aug 21, 2025
2777e18
add type to product
ikethecoder Aug 21, 2025
602aeba
upd product
ikethecoder Aug 21, 2025
eab886c
adj env spec
ikethecoder Aug 21, 2025
ca6075c
adj env spec
ikethecoder Aug 21, 2025
068ae88
include environments in products list
ikethecoder Aug 21, 2025
fffb9eb
set org for product
ikethecoder Aug 21, 2025
23743f4
add client certificate as an option
ikethecoder Aug 22, 2025
f2fd812
support client certificate
ikethecoder Aug 22, 2025
c39374c
add client certificate support
ikethecoder Aug 22, 2025
dea1408
add subjectdn to results
ikethecoder Aug 22, 2025
857a342
upd activity details
ikethecoder Aug 22, 2025
1c3429b
remove hardcoded item
ikethecoder Aug 22, 2025
9ad0cb4
upd test
ikethecoder Aug 22, 2025
b4bfbc3
add new dropdown to crediss
ikethecoder Aug 22, 2025
f105c13
more integration testing
ikethecoder Aug 22, 2025
2d9b5a3
workaround for token exchange
ikethecoder Aug 23, 2025
036ecfb
add access request retrieval
ikethecoder Aug 23, 2025
8ccf39d
add org access requests apis
ikethecoder Aug 23, 2025
88395dd
upd test
ikethecoder Aug 29, 2025
9d81c12
add to org access requests api
ikethecoder Aug 29, 2025
32a31c0
cleanup org access req
ikethecoder Aug 29, 2025
fcffda5
upd org access request
ikethecoder Aug 30, 2025
0a86dbd
add org create access request
ikethecoder Aug 30, 2025
9974069
try getting userid another way
ikethecoder Aug 30, 2025
d36ab3f
try getting userid another way
ikethecoder Aug 30, 2025
6218ca9
try getting userid another way
ikethecoder Aug 30, 2025
6197732
add org access request creation
ikethecoder Sep 2, 2025
c3efdf4
upd org access request
ikethecoder Sep 2, 2025
499efc4
fix errored controller
ikethecoder Sep 2, 2025
c317b98
fix org access request err
ikethecoder Sep 2, 2025
726dd94
adj create access req
ikethecoder Sep 3, 2025
04c71f3
try fix issue with access request save
ikethecoder Sep 3, 2025
dc0dc3b
tweak org access request api
ikethecoder Sep 3, 2025
bd8219d
skip access control for creating access request
ikethecoder Sep 3, 2025
141b36c
change delete org access to service access
ikethecoder Sep 3, 2025
925eeda
include more gateway information
ikethecoder Sep 3, 2025
b0f0b78
upd perm for org access req creation
ikethecoder Sep 3, 2025
a34491a
have some tsoa be user called only
ikethecoder Sep 4, 2025
8d18425
temp disable validation
ikethecoder Sep 4, 2025
5bfbe18
remove need for passing userid to create req
ikethecoder Sep 4, 2025
1a51d0c
minor fix on create req
ikethecoder Sep 4, 2025
af60cb4
add apispec update
ikethecoder Sep 4, 2025
5d68b2d
add get api_spec
ikethecoder Sep 4, 2025
3130e51
tweak api_spec
ikethecoder Sep 4, 2025
03ad2f3
tweak api_spec
ikethecoder Sep 4, 2025
dca955a
upd get apispecs
ikethecoder Sep 4, 2025
97bee65
fix org unit issue
ikethecoder Sep 8, 2025
a29af94
exclude decommissioned ns
ikethecoder Sep 8, 2025
983c656
enable consent
ikethecoder Sep 10, 2025
bc39681
temporarily remove perms to get openapi spec
ikethecoder Sep 10, 2025
5dba438
temporarily remove perms to get openapi spec
ikethecoder Sep 10, 2025
b47048e
still working on org api spec
ikethecoder Sep 10, 2025
571cf72
still working on org api spec
ikethecoder Sep 10, 2025
7d10656
udp product catalog api
ikethecoder Sep 10, 2025
4817161
upd catalog list
ikethecoder Sep 10, 2025
73a7297
include org param for catalog
ikethecoder Sep 11, 2025
a6d2671
v3 api tweak
ikethecoder Sep 11, 2025
568b5d9
adj catalog output
ikethecoder Sep 11, 2025
f51f079
adj catalog ns output
ikethecoder Sep 11, 2025
8927f4e
fix catalog list
ikethecoder Sep 11, 2025
3798d95
fix catalog list
ikethecoder Sep 11, 2025
cb8cda9
fix catalog list
ikethecoder Sep 11, 2025
86dd85e
adj product catalog add issuer details
ikethecoder Sep 11, 2025
e73c90a
fix label saving
ikethecoder Sep 12, 2025
fdd69a6
fix label saving
ikethecoder Sep 12, 2025
20910a5
accomodate no org unit
ikethecoder Sep 12, 2025
879f107
change client name
ikethecoder Sep 12, 2025
9974c0d
add more to product catalog spec
ikethecoder Sep 12, 2025
1513fff
try and fix subjectDN not working
ikethecoder Sep 12, 2025
692f378
try and fix subjectDN not working
ikethecoder Sep 12, 2025
1d1f32d
boost speed on catalog call
ikethecoder Sep 26, 2025
48faf9c
new sdx controller
ikethecoder Dec 3, 2025
e2cd0ab
fix controller bug
ikethecoder Dec 3, 2025
7ddf3d1
allow for any params
ikethecoder Dec 4, 2025
3a1463c
add support for delete and change pattern payload
ikethecoder Dec 4, 2025
ac8b478
upd catalog
ikethecoder Dec 4, 2025
522473c
fix sdx controller
ikethecoder Dec 4, 2025
b18486f
fix sdx controller
ikethecoder Dec 4, 2025
0241d35
fix delete qualifier
ikethecoder Dec 4, 2025
7213e22
upd sdx controller
ikethecoder Dec 4, 2025
a36b7b6
adj patterns
ikethecoder Dec 4, 2025
d0f0e04
adj error
ikethecoder Dec 4, 2025
ffe6040
upd missing edge server details
ikethecoder Dec 4, 2025
9504cb2
adj gateway pattern
ikethecoder Dec 4, 2025
59d74ff
adj pattern
ikethecoder Dec 4, 2025
875eff2
add edge_kid
ikethecoder Dec 5, 2025
7b638e4
add edge_kid
ikethecoder Dec 5, 2025
b995b8b
add jwks endpoint to org
ikethecoder Dec 6, 2025
fc56ef9
integrated test for product apispec
ikethecoder Dec 17, 2025
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
4 changes: 4 additions & 0 deletions src/auth/methods.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,9 @@
"github": {
"text": "Github",
"description": ""
},
"digitalcredential": {
"text": "Digital Credential",
"description": "A digital credential that proves your identity and is issued by a trusted authority."
}
}
24 changes: 21 additions & 3 deletions src/batch/data-rules.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

const metadata = {
Organization: {
query: 'allOrganizations',
Expand All @@ -18,6 +19,7 @@ const metadata = {
name: 'connectExclusiveListCreate',
list: 'OrganizationUnit',
syncFirst: true,
refKey: 'extForeignKey',
},
},
},
Expand Down Expand Up @@ -387,7 +389,7 @@ const metadata = {
Application: {
query: 'allApplications',
refKey: 'appId',
sync: ['name', 'description'],
sync: ['name', 'description', 'namespace'],
transformations: {
owner: { name: 'connectOne', list: 'allUsers', refKey: 'username' },
organization: {
Expand All @@ -408,19 +410,32 @@ const metadata = {
query: 'allProducts',
refKey: 'appId',
compositeRefKey: ['name', 'namespace'],
sync: ['name', 'description', 'namespace'],
sync: ['name', 'type', 'description', 'namespace', 'organization', 'openapiSpecs'],
transformations: {
dataset: { name: 'connectOne', list: 'allDatasets', refKey: 'name' },
openapiSpecs: { name: "toStringDefaultArray" },
environments: {
name: 'connectExclusiveListCreate',
list: 'Environment',
syncFirst: true,
refKey: 'appId',
},
organization: {
name: 'connectOne',
list: 'allOrganizations',
refKey: 'name',
},
},
validations: {
type: {
type: 'enum',
values: ['app', 'service'],
},
},
example: {
name: 'my-new-product',
appId: '000000000000',
type: 'service',
environments: [
{
name: 'dev',
Expand Down Expand Up @@ -449,6 +464,9 @@ const metadata = {
filterByNamespace: true,
},
legal: { name: 'connectOne', list: 'allLegals', refKey: 'reference' },
// exclude "spec" otherwise batch reading will automatically try to read it
// which we don't necessarily want
// spec: { name: 'connectOne', list: 'allBlobs', refKey: 'name' },
credentialIssuer: {
name: 'connectOne',
list: 'allCredentialIssuers',
Expand Down Expand Up @@ -530,7 +548,7 @@ const metadata = {
mode: { type: 'enum', values: ['auto'] },
clientAuthenticator: {
type: 'enum',
values: ['client-secret', 'client-jwt', 'client-jwt-jwks-url'],
values: ['client-secret', 'client-jwt', 'client-jwt-jwks-url', 'client-certificate'],
},
environmentDetails: {
type: 'entityArray',
Expand Down
3 changes: 2 additions & 1 deletion src/batch/feed-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ function buildQueryResponse(md: any, children: string[] = undefined): string[] {
.slice();
response.push(md.refKey);

logger.debug('[buildQueryResponse] DRAFT (%s) %j', md.query, response);
logger.debug('[buildQueryResponse] DRAFT (%s) (%s) %j', children, md.query, response);
if (children) {
relationshipFields.forEach((field: string) => {
// populate the fields as well
Expand Down Expand Up @@ -511,6 +511,7 @@ export const syncRecords = async function (
const transformInfo = md.transformations[transformKey];
if (transformInfo.syncFirst) {
// handle these children independently first - return a list of IDs

const allIds = await syncListOfRecords(
context,
transformInfo,
Expand Down
44 changes: 44 additions & 0 deletions src/controllers/ioc/keystoneInjector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Keystone } from '@keystonejs/keystone';
import { injectable } from 'tsyringe';
import { scopes, scopesToRoles } from '../../auth/scope-role-utils';
import { Logger } from '../../logger';
import { lookupUserByUsername } from '../../services/keystone';

const logger = Logger('controller');

Expand Down Expand Up @@ -38,6 +39,49 @@ export class KeystoneService {
return this.keystone.createContext({ skipAccessControl: true });
}

public async createContextithUser(
request: any,
skipAccessControl: boolean = false
) {
const _scopes = scopes(request.user.scope);

const identityProvider = request.user.identity_provider;

if (!request.user && !request.user.preferred_username) {
throw new Error(
'User information is required to create context with user'
);
}
const tmpCtx = this.keystone.createContext({
skipAccessControl: true,
});
const users = await lookupUserByUsername(
tmpCtx,
request.user.preferred_username
);
if (!users) {
throw new Error(`User ${request.user.preferred_username} not found`);
}
const userId = users[0].id;

const identity = {
id: null,
name: resolveName(request.user),
username: resolveUsername(request.user),
namespace: request.params.ns || request.params.gatewayId,
roles: JSON.stringify(scopesToRoles(identityProvider, _scopes)),
scopes: _scopes,
userId,
} as any;
logger.debug('identity %j', identity);
const ctx = this.keystone.createContext({
skipAccessControl,
authentication: { item: identity },
});
ctx.req = request;
return ctx;
}

public createContext(request: any, skipAccessControl: boolean = false): any {
const _scopes = scopes(request.user.scope);

Expand Down
21 changes: 21 additions & 0 deletions src/controllers/v2/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ components:
- client-secret
- client-jwt
- client-jwt-jwks-url
- client-certificate
instruction:
type: string
environmentDetails:
Expand Down Expand Up @@ -579,13 +580,21 @@ components:
type: string
enabled:
type: boolean
permDataPlane:
type: string
permDomains:
items:
type: string
type: array
updatedAt:
type: number
format: double
required:
- name
- orgUnit
- enabled
- permDataPlane
- permDomains
- updatedAt
type: object
additionalProperties: false
Expand Down Expand Up @@ -645,21 +654,33 @@ components:
type: string
name:
type: string
type:
type: string
enum:
- app
- service
description:
type: string
namespace:
type: string
openapiSpecs:
items:
type: string
type: array
dataset:
$ref: '#/components/schemas/DraftDatasetRefID'
environments:
items:
$ref: '#/components/schemas/Environment'
type: array
organization:
$ref: '#/components/schemas/OrganizationRefID'
type: object
additionalProperties: false
example:
name: my-new-product
appId: '000000000000'
type: service
environments:
-
name: dev
Expand Down
7 changes: 6 additions & 1 deletion src/controllers/v2/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ const models: TsoaRoute.Models = {
"flow": {"dataType":"enum","enums":["client-credentials"]},
"mode": {"dataType":"enum","enums":["auto"]},
"authPlugin": {"dataType":"string"},
"clientAuthenticator": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["client-secret"]},{"dataType":"enum","enums":["client-jwt"]},{"dataType":"enum","enums":["client-jwt-jwks-url"]}]},
"clientAuthenticator": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["client-secret"]},{"dataType":"enum","enums":["client-jwt"]},{"dataType":"enum","enums":["client-jwt-jwks-url"]},{"dataType":"enum","enums":["client-certificate"]}]},
"instruction": {"dataType":"string"},
"environmentDetails": {"dataType":"array","array":{"dataType":"refObject","ref":"IssuerEnvironmentConfig"}},
"resourceType": {"dataType":"string"},
Expand Down Expand Up @@ -373,6 +373,8 @@ const models: TsoaRoute.Models = {
"name": {"dataType":"string","required":true},
"orgUnit": {"dataType":"string","required":true},
"enabled": {"dataType":"boolean","required":true},
"permDataPlane": {"dataType":"string","required":true},
"permDomains": {"dataType":"array","array":{"dataType":"string"},"required":true},
"updatedAt": {"dataType":"double","required":true},
},
"additionalProperties": false,
Expand Down Expand Up @@ -414,10 +416,13 @@ const models: TsoaRoute.Models = {
"properties": {
"appId": {"dataType":"string"},
"name": {"dataType":"string"},
"type": {"dataType":"union","subSchemas":[{"dataType":"enum","enums":["app"]},{"dataType":"enum","enums":["service"]}]},
"description": {"dataType":"string"},
"namespace": {"dataType":"string"},
"openapiSpecs": {"dataType":"array","array":{"dataType":"string"}},
"dataset": {"ref":"DraftDatasetRefID"},
"environments": {"dataType":"array","array":{"dataType":"refObject","ref":"Environment"}},
"organization": {"ref":"OrganizationRefID"},
},
"additionalProperties": false,
},
Expand Down
7 changes: 6 additions & 1 deletion src/controllers/v2/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ export interface Application {
appId?: string; // Primary Key
name?: string;
description?: string;
namespace?: string;
owner?: UserRefID;
organization?: OrganizationRefID;
organizationUnit?: OrganizationUnitRefID;
Expand All @@ -274,6 +275,7 @@ export interface Application {
* @example {
* "name": "my-new-product",
* "appId": "000000000000",
* "type": "service",
* "environments": [
* {
* "name": "dev",
Expand All @@ -288,10 +290,13 @@ export interface Application {
export interface Product {
appId?: string; // Primary Key
name?: string;
type?: "app" | "service";
description?: string;
namespace?: string;
openapiSpecs?: string[];
dataset?: DraftDatasetRefID;
environments?: Environment[];
organization?: OrganizationRefID;
}


Expand Down Expand Up @@ -337,7 +342,7 @@ export interface CredentialIssuer {
flow?: "client-credentials";
mode?: "auto";
authPlugin?: string;
clientAuthenticator?: "client-secret" | "client-jwt" | "client-jwt-jwks-url";
clientAuthenticator?: "client-secret" | "client-jwt" | "client-jwt-jwks-url" | "client-certificate";
instruction?: string;
environmentDetails?: IssuerEnvironmentConfig[];
resourceType?: string;
Expand Down
1 change: 1 addition & 0 deletions src/controllers/v3/GatewayServicesController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export class GatewayController extends Controller {
@OperationId('publish-gateway-config')
@Security('jwt', ['Gateway.Config'])
public async put(
@Path() gatewayId: string,
@FormField() dryRun: boolean,
@UploadedFile() configFile: Express.Multer.File
): Promise<PublishResult> {
Expand Down
69 changes: 69 additions & 0 deletions src/controllers/v3/OrgAPISpecController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {
Controller,
Request,
OperationId,
Put,
Path,
Route,
Security,
Body,
Tags,
Get,
} from 'tsoa';
import { KeystoneService } from '../ioc/keystoneInjector';
import { inject, injectable } from 'tsyringe';
import { OrgAPISpecCreateInput } from './types-extra';
import { Logger } from '../../logger';
import { gql } from 'graphql-request';
import { UpdateAPISpec, GetAPISpecsByOrg } from '../../services/workflow/api-specs';

const logger = Logger('controllers.OrgAPISpec');

@injectable()
@Route('/organizations')
@Tags('Organizations')
export class OrgAPISpecController extends Controller {
private keystone: KeystoneService;
constructor(@inject('KeystoneService') private _keystone: KeystoneService) {
super();
this.keystone = _keystone;
}

/**
* Update API Specification for a Product Environment
* > `Required Scope:` Namespace.Assign
*
* @summary Manage Access Requests
* @param ns
* @param body
* @param request
*/
@Put('/{org}/api_specs')
@OperationId('organization-put-access-requests')
@Security('jwt', ['Namespace.Assign'])
public async put(
@Path() org: string,
@Body() body: OrgAPISpecCreateInput,
@Request() request: any
): Promise<{ id: string }> {
const ctx = await this.keystone.createContextithUser(request, true);

const result = await UpdateAPISpec(ctx, body.specUrl, body.productEnvAppId);
logger.debug('OrgAPISpecController: %j', result);
return { id: result.id };
}

@Get('/{org}/api_specs')
@OperationId('organization-get-api-specs')
//@Security('jwt', ['Namespace.Assign'])
public async get(
@Path() org: string,
@Request() request: any
): Promise<{ prodEnvId: string; spec: string }> {
const ctx = this.keystone.sudo();
//const ctx = await this.keystone.createContext(request, true);
const result = await GetAPISpecsByOrg(ctx, org);
logger.debug('OrgAPISpecController: %j', result);
return result;
}
}
Loading
Loading