@solidxai/core 0.1.8-beta.8 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +197 -0
- package/dist/controllers/authentication.controller.d.ts +32 -2
- package/dist/controllers/authentication.controller.d.ts.map +1 -1
- package/dist/controllers/authentication.controller.js +80 -3
- package/dist/controllers/authentication.controller.js.map +1 -1
- package/dist/dtos/create-api-key.dto.d.ts +5 -0
- package/dist/dtos/create-api-key.dto.d.ts.map +1 -0
- package/dist/dtos/create-api-key.dto.js +34 -0
- package/dist/dtos/create-api-key.dto.js.map +1 -0
- package/dist/dtos/register-private.dto.d.ts +3 -5
- package/dist/dtos/register-private.dto.d.ts.map +1 -1
- package/dist/dtos/register-private.dto.js +6 -18
- package/dist/dtos/register-private.dto.js.map +1 -1
- package/dist/dtos/sso-exchange.dto.d.ts +4 -0
- package/dist/dtos/sso-exchange.dto.d.ts.map +1 -0
- package/dist/dtos/sso-exchange.dto.js +26 -0
- package/dist/dtos/sso-exchange.dto.js.map +1 -0
- package/dist/dtos/update-api-key.dto.d.ts +4 -0
- package/dist/dtos/update-api-key.dto.d.ts.map +1 -0
- package/dist/dtos/update-api-key.dto.js +28 -0
- package/dist/dtos/update-api-key.dto.js.map +1 -0
- package/dist/entities/agent-event.entity.js +1 -1
- package/dist/entities/agent-event.entity.js.map +1 -1
- package/dist/entities/agent-session.entity.js +1 -1
- package/dist/entities/agent-session.entity.js.map +1 -1
- package/dist/entities/setting.entity.d.ts +1 -0
- package/dist/entities/setting.entity.d.ts.map +1 -1
- package/dist/entities/setting.entity.js +5 -1
- package/dist/entities/setting.entity.js.map +1 -1
- package/dist/entities/user-api-key.entity.d.ts +12 -0
- package/dist/entities/user-api-key.entity.d.ts.map +1 -0
- package/dist/entities/user-api-key.entity.js +62 -0
- package/dist/entities/user-api-key.entity.js.map +1 -0
- package/dist/entities/user.entity.d.ts +3 -0
- package/dist/entities/user.entity.d.ts.map +1 -1
- package/dist/entities/user.entity.js +12 -1
- package/dist/entities/user.entity.js.map +1 -1
- package/dist/enums/auth-type.enum.d.ts +2 -1
- package/dist/enums/auth-type.enum.d.ts.map +1 -1
- package/dist/enums/auth-type.enum.js +2 -1
- package/dist/enums/auth-type.enum.js.map +1 -1
- package/dist/guards/api-key.guard.d.ts +11 -0
- package/dist/guards/api-key.guard.d.ts.map +1 -0
- package/dist/guards/api-key.guard.js +43 -0
- package/dist/guards/api-key.guard.js.map +1 -0
- package/dist/guards/authentication.guard.d.ts +4 -2
- package/dist/guards/authentication.guard.d.ts.map +1 -1
- package/dist/guards/authentication.guard.js +7 -3
- package/dist/guards/authentication.guard.js.map +1 -1
- package/dist/helpers/bootstrap.helper.d.ts.map +1 -1
- package/dist/helpers/bootstrap.helper.js +11 -0
- package/dist/helpers/bootstrap.helper.js.map +1 -1
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js +15 -6
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +12 -0
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts +1 -1
- package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts.map +1 -1
- package/dist/jobs/database/chatter-queue-publisher-database.service.js.map +1 -1
- package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts +1 -1
- package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts.map +1 -1
- package/dist/jobs/database/chatter-queue-subscriber-database.service.js.map +1 -1
- package/dist/jobs/rabbitmq/chatter-queue-publisher.service.d.ts +1 -12
- package/dist/jobs/rabbitmq/chatter-queue-publisher.service.d.ts.map +1 -1
- package/dist/jobs/rabbitmq/chatter-queue-publisher.service.js.map +1 -1
- package/dist/jobs/rabbitmq/chatter-queue-subscriber.service.d.ts +1 -1
- package/dist/jobs/rabbitmq/chatter-queue-subscriber.service.d.ts.map +1 -1
- package/dist/jobs/rabbitmq/chatter-queue-subscriber.service.js.map +1 -1
- package/dist/jobs/redis/chatter-queue-subscriber-redis.service.d.ts +1 -1
- package/dist/jobs/redis/chatter-queue-subscriber-redis.service.d.ts.map +1 -1
- package/dist/jobs/redis/chatter-queue-subscriber-redis.service.js.map +1 -1
- package/dist/repository/user-api-key.repository.d.ts +12 -0
- package/dist/repository/user-api-key.repository.d.ts.map +1 -0
- package/dist/repository/user-api-key.repository.js +34 -0
- package/dist/repository/user-api-key.repository.js.map +1 -0
- package/dist/seeders/seed-data/solid-core-metadata.json +145 -20
- package/dist/services/api-key.service.d.ts +20 -0
- package/dist/services/api-key.service.d.ts.map +1 -0
- package/dist/services/api-key.service.js +98 -0
- package/dist/services/api-key.service.js.map +1 -0
- package/dist/services/authentication.service.d.ts +19 -1
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +31 -5
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/encryption.service.d.ts +8 -0
- package/dist/services/encryption.service.d.ts.map +1 -0
- package/dist/services/encryption.service.js +75 -0
- package/dist/services/encryption.service.js.map +1 -0
- package/dist/services/setting.service.d.ts +1 -0
- package/dist/services/setting.service.d.ts.map +1 -1
- package/dist/services/setting.service.js +35 -7
- package/dist/services/setting.service.js.map +1 -1
- package/dist/services/settings/default-settings-provider.service.d.ts +12 -0
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +4 -3
- package/dist/services/settings/default-settings-provider.service.js.map +1 -1
- package/dist/services/sso-code-storage.service.d.ts +15 -0
- package/dist/services/sso-code-storage.service.d.ts.map +1 -0
- package/dist/services/sso-code-storage.service.js +47 -0
- package/dist/services/sso-code-storage.service.js.map +1 -0
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +10 -0
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/audit.subscriber.d.ts +1 -1
- package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
- package/dist/subscribers/audit.subscriber.js.map +1 -1
- package/package.json +1 -1
- package/src/controllers/authentication.controller.ts +59 -3
- package/src/dtos/create-api-key.dto.ts +14 -0
- package/src/dtos/register-private.dto.ts +5 -14
- package/src/dtos/sso-exchange.dto.ts +7 -0
- package/src/dtos/update-api-key.dto.ts +9 -0
- package/src/entities/agent-event.entity.ts +1 -1
- package/src/entities/agent-session.entity.ts +1 -1
- package/src/entities/setting.entity.ts +3 -0
- package/src/entities/user-api-key.entity.ts +37 -0
- package/src/entities/user.entity.ts +8 -0
- package/src/enums/auth-type.enum.ts +1 -0
- package/src/guards/api-key.guard.ts +32 -0
- package/src/guards/authentication.guard.ts +6 -3
- package/src/helpers/bootstrap.helper.ts +15 -0
- package/src/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.ts +17 -6
- package/src/index.ts +2 -0
- package/src/interfaces.ts +16 -0
- package/src/jobs/database/chatter-queue-publisher-database.service.ts +1 -1
- package/src/jobs/database/chatter-queue-subscriber-database.service.ts +1 -1
- package/src/jobs/rabbitmq/chatter-queue-publisher.service.ts +1 -15
- package/src/jobs/rabbitmq/chatter-queue-subscriber.service.ts +1 -1
- package/src/jobs/redis/chatter-queue-subscriber-redis.service.ts +1 -1
- package/src/repository/user-api-key.repository.ts +17 -0
- package/src/seeders/seed-data/solid-core-metadata.json +145 -20
- package/src/services/api-key.service.ts +111 -0
- package/src/services/authentication.service.ts +35 -3
- package/src/services/encryption.service.ts +43 -0
- package/src/services/setting.service.ts +38 -9
- package/src/services/settings/default-settings-provider.service.ts +4 -3
- package/src/services/sso-code-storage.service.ts +36 -0
- package/src/solid-core.module.ts +10 -0
- package/src/subscribers/audit.subscriber.ts +1 -1
|
@@ -1,17 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export class RegisterPrivateDto {
|
|
4
|
-
@IsNotEmpty()
|
|
5
|
-
username: string;
|
|
6
|
-
|
|
7
|
-
@IsEmail()
|
|
8
|
-
@IsNotEmpty()
|
|
9
|
-
email: string;
|
|
10
|
-
|
|
11
|
-
@IsOptional()
|
|
12
|
-
mobile?: string;
|
|
1
|
+
import { IsBoolean, IsOptional } from 'class-validator';
|
|
2
|
+
import { SignUpDto } from './sign-up.dto';
|
|
13
3
|
|
|
4
|
+
export class RegisterPrivateDto extends SignUpDto {
|
|
5
|
+
@IsBoolean()
|
|
14
6
|
@IsOptional()
|
|
15
|
-
|
|
16
|
-
password?: string;
|
|
7
|
+
isAllowedToGenerateApiKeys?: boolean;
|
|
17
8
|
}
|
|
@@ -2,7 +2,7 @@ import { Column, Entity, Index } from 'typeorm';
|
|
|
2
2
|
import { CommonEntity } from 'src/entities/common.entity';
|
|
3
3
|
import { getColumnType } from 'src/helpers/typeorm-db-helper';
|
|
4
4
|
|
|
5
|
-
@Entity({ name: 'ss_agent_events'
|
|
5
|
+
@Entity({ name: 'ss_agent_events' })
|
|
6
6
|
export class AgentEvent extends CommonEntity {
|
|
7
7
|
@Index()
|
|
8
8
|
@Column({ })
|
|
@@ -2,7 +2,7 @@ import { Column, Entity, Index } from 'typeorm';
|
|
|
2
2
|
import { CommonEntity } from 'src/entities/common.entity';
|
|
3
3
|
import { getColumnType } from 'src/helpers/typeorm-db-helper';
|
|
4
4
|
|
|
5
|
-
@Entity({ name: 'ss_agent_sessions'
|
|
5
|
+
@Entity({ name: 'ss_agent_sessions' })
|
|
6
6
|
export class AgentSession extends CommonEntity {
|
|
7
7
|
@Index({ unique: true })
|
|
8
8
|
@Column({ })
|
|
@@ -19,6 +19,9 @@ export class Setting extends CommonEntity {
|
|
|
19
19
|
@Column({ name: "level", type: "varchar", nullable: true })
|
|
20
20
|
level: string;
|
|
21
21
|
|
|
22
|
+
@Column({ name: "encrypted", type: "boolean", default: false })
|
|
23
|
+
encrypted: boolean;
|
|
24
|
+
|
|
22
25
|
@Index()
|
|
23
26
|
@ManyToOne(() => User, { nullable: true })
|
|
24
27
|
@JoinColumn()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Exclude, Expose } from "class-transformer";
|
|
2
|
+
import { CommonEntity } from "src/entities/common.entity";
|
|
3
|
+
import { Column, Entity, Index, ManyToOne } from "typeorm";
|
|
4
|
+
import { User } from "./user.entity";
|
|
5
|
+
|
|
6
|
+
@Entity("ss_user_api_key")
|
|
7
|
+
@Exclude()
|
|
8
|
+
export class UserApiKey extends CommonEntity {
|
|
9
|
+
|
|
10
|
+
@Expose()
|
|
11
|
+
@Column()
|
|
12
|
+
name: string;
|
|
13
|
+
|
|
14
|
+
// SHA-256 hash of the raw key — never exposed, same treatment as User.password
|
|
15
|
+
@Index({ unique: true })
|
|
16
|
+
@Column()
|
|
17
|
+
hashedKey: string;
|
|
18
|
+
|
|
19
|
+
@Expose()
|
|
20
|
+
@Column()
|
|
21
|
+
maskedKey: string;
|
|
22
|
+
|
|
23
|
+
@Expose()
|
|
24
|
+
@Column({ default: true })
|
|
25
|
+
isActive: boolean;
|
|
26
|
+
|
|
27
|
+
@Expose()
|
|
28
|
+
@Column({ nullable: true })
|
|
29
|
+
expiresAt: Date;
|
|
30
|
+
|
|
31
|
+
@Expose()
|
|
32
|
+
@Column({ nullable: true })
|
|
33
|
+
lastUsedAt: Date;
|
|
34
|
+
|
|
35
|
+
@ManyToOne(() => User, user => user.apiKeys)
|
|
36
|
+
user: User;
|
|
37
|
+
}
|
|
@@ -2,6 +2,7 @@ import { CommonEntity } from "src/entities/common.entity"
|
|
|
2
2
|
import { Entity, Column, Index, JoinTable, ManyToMany, OneToMany, TableInheritance } from "typeorm";
|
|
3
3
|
import { RoleMetadata } from 'src/entities/role-metadata.entity';
|
|
4
4
|
import { UserViewMetadata } from 'src/entities/user-view-metadata.entity'
|
|
5
|
+
import { UserApiKey } from 'src/entities/user-api-key.entity'
|
|
5
6
|
import { Exclude, Expose } from "class-transformer";
|
|
6
7
|
|
|
7
8
|
@Entity("ss_user")
|
|
@@ -151,4 +152,11 @@ export class User extends CommonEntity {
|
|
|
151
152
|
@Expose()
|
|
152
153
|
_media: any;
|
|
153
154
|
|
|
155
|
+
@Column({ default: false })
|
|
156
|
+
@Expose()
|
|
157
|
+
isAllowedToGenerateApiKeys: boolean = false;
|
|
158
|
+
|
|
159
|
+
@OneToMany(() => UserApiKey, key => key.user)
|
|
160
|
+
apiKeys: UserApiKey[];
|
|
161
|
+
|
|
154
162
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';
|
|
2
|
+
import { Request } from 'express';
|
|
3
|
+
import { REQUEST_USER_KEY } from 'src/constants';
|
|
4
|
+
import { ApiKeyService } from 'src/services/api-key.service';
|
|
5
|
+
import { ClsService } from 'nestjs-cls';
|
|
6
|
+
|
|
7
|
+
@Injectable()
|
|
8
|
+
export class ApiKeyGuard implements CanActivate {
|
|
9
|
+
constructor(
|
|
10
|
+
private readonly apiKeyService: ApiKeyService,
|
|
11
|
+
private readonly cls: ClsService,
|
|
12
|
+
) {}
|
|
13
|
+
|
|
14
|
+
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
15
|
+
const request = context.switchToHttp().getRequest<Request>();
|
|
16
|
+
const rawKey = this.extractKeyFromHeader(request);
|
|
17
|
+
|
|
18
|
+
if (!rawKey) {
|
|
19
|
+
throw new UnauthorizedException();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const activeUser = await this.apiKeyService.validate(rawKey);
|
|
23
|
+
request[REQUEST_USER_KEY] = activeUser;
|
|
24
|
+
this.cls.set(REQUEST_USER_KEY, activeUser);
|
|
25
|
+
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private extractKeyFromHeader(request: Request): string | undefined {
|
|
30
|
+
return request.headers['solidx-api-key'] as string | undefined;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -8,23 +8,26 @@ import { Reflector } from '@nestjs/core';
|
|
|
8
8
|
import { AUTH_TYPE_KEY } from '../decorators/auth.decorator';
|
|
9
9
|
import { AuthType } from '../enums/auth-type.enum';
|
|
10
10
|
import { AccessTokenGuard } from './access-token.guard';
|
|
11
|
+
import { ApiKeyGuard } from './api-key.guard';
|
|
11
12
|
import { IS_PUBLIC_KEY } from '../decorators/public.decorator';
|
|
12
13
|
import { PermissionMetadataService } from '../services/permission-metadata.service';
|
|
13
14
|
import { ClsService } from 'nestjs-cls';
|
|
14
15
|
|
|
15
16
|
@Injectable()
|
|
16
17
|
export class AuthenticationGuard implements CanActivate {
|
|
17
|
-
private static readonly
|
|
18
|
+
private static readonly defaultAuthTypes = [AuthType.Bearer, AuthType.ApiKey];
|
|
18
19
|
private readonly authTypeGuardMap: Record<
|
|
19
20
|
AuthType,
|
|
20
21
|
CanActivate | CanActivate[]> = {
|
|
21
22
|
[AuthType.Bearer]: this.accessTokenGuard,
|
|
23
|
+
[AuthType.ApiKey]: this.apiKeyGuard,
|
|
22
24
|
[AuthType.None]: { canActivate: () => true },
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
constructor(
|
|
26
28
|
private readonly reflector: Reflector,
|
|
27
29
|
private readonly accessTokenGuard: AccessTokenGuard,
|
|
30
|
+
private readonly apiKeyGuard: ApiKeyGuard,
|
|
28
31
|
private readonly permissionService: PermissionMetadataService,
|
|
29
32
|
private readonly cls: ClsService,
|
|
30
33
|
) { }
|
|
@@ -49,7 +52,7 @@ export class AuthenticationGuard implements CanActivate {
|
|
|
49
52
|
return true;
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
// TODO: Check if this permission viz. contextPermission is listed in the Public role.
|
|
55
|
+
// TODO: Check if this permission viz. contextPermission is listed in the Public role.
|
|
53
56
|
const contextPermission = `${context.getClass().name}.${context.getHandler().name}`;
|
|
54
57
|
|
|
55
58
|
const permissionExistsInRole = await this.permissionService.permissionExistsInRole('Public', contextPermission)
|
|
@@ -61,7 +64,7 @@ export class AuthenticationGuard implements CanActivate {
|
|
|
61
64
|
const authTypes = this.reflector.getAllAndOverride<AuthType[]>(
|
|
62
65
|
AUTH_TYPE_KEY,
|
|
63
66
|
[context.getHandler(), context.getClass()],
|
|
64
|
-
) ??
|
|
67
|
+
) ?? AuthenticationGuard.defaultAuthTypes;
|
|
65
68
|
const guards = authTypes.map((type) => this.authTypeGuardMap[type]).flat();
|
|
66
69
|
let error = new UnauthorizedException();
|
|
67
70
|
|
|
@@ -90,6 +90,21 @@ export async function bootstrapSolidApp(
|
|
|
90
90
|
// Security headers
|
|
91
91
|
app.use(helmet(buildDefaultSecurityHeaderOptions()));
|
|
92
92
|
|
|
93
|
+
// Nest's Swagger UI HTML injects inline styles; keep CSP strict elsewhere.
|
|
94
|
+
const isSwaggerPath = (path: string) =>
|
|
95
|
+
path === '/docs' ||
|
|
96
|
+
path === '/docs/' ||
|
|
97
|
+
path.startsWith('/docs/') ||
|
|
98
|
+
path === '/docs-json' ||
|
|
99
|
+
path === '/docs-yaml';
|
|
100
|
+
|
|
101
|
+
app.use((req: Request, res: Response, next: NextFunction) => {
|
|
102
|
+
if (isSwaggerPath(req.path)) {
|
|
103
|
+
res.removeHeader('Content-Security-Policy');
|
|
104
|
+
}
|
|
105
|
+
next();
|
|
106
|
+
});
|
|
107
|
+
|
|
93
108
|
// Permissions-Policy header
|
|
94
109
|
app.use((_req: Request, res: Response, next: NextFunction) => {
|
|
95
110
|
res.setHeader('Permissions-Policy', buildPermissionsPolicyHeader(permissionsPolicyOverrides));
|
|
@@ -128,14 +128,25 @@ export class SelectionDynamicFieldCrudManager implements FieldCrudManager {
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
private providerInstance<T extends ISelectionProviderContext>(selectionDynamicProvider: string): ISelectionProvider<T> {
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
const providers = this.options.discoveryService.getProviders();
|
|
132
|
+
|
|
133
|
+
const byToken = providers.find((p) => p.name === selectionDynamicProvider);
|
|
134
|
+
if (byToken) {
|
|
135
|
+
return byToken.instance as ISelectionProvider<T>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const byName = providers.find((p) => {
|
|
139
|
+
try {
|
|
140
|
+
return typeof p.instance?.name === 'function' && p.instance.name() === selectionDynamicProvider;
|
|
141
|
+
} catch {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
if (!byName) {
|
|
136
147
|
throw new Error(`Provider for ${selectionDynamicProvider} not found`);
|
|
137
148
|
}
|
|
138
|
-
return
|
|
149
|
+
return byName.instance as ISelectionProvider<T>;
|
|
139
150
|
}
|
|
140
151
|
|
|
141
152
|
private isApplyRequiredValidation(): boolean {
|
package/src/index.ts
CHANGED
|
@@ -126,6 +126,7 @@ export * from './entities/permission-metadata.entity'
|
|
|
126
126
|
export * from './entities/role-metadata.entity'
|
|
127
127
|
export * from './entities/sms-template.entity'
|
|
128
128
|
export * from './entities/user.entity'
|
|
129
|
+
export * from './entities/user-api-key.entity'
|
|
129
130
|
export * from './entities/view-metadata.entity'
|
|
130
131
|
export * from './entities/setting.entity'
|
|
131
132
|
export * from './entities/saved-filters.entity'
|
|
@@ -314,6 +315,7 @@ export * from './services/user.service'
|
|
|
314
315
|
export * from './services/view-metadata.service'
|
|
315
316
|
export * from './services/whatsapp/Msg91WhatsappService' //rename
|
|
316
317
|
export * from './services/setting.service'
|
|
318
|
+
export * from './services/encryption.service'
|
|
317
319
|
export * from './services/info.service'
|
|
318
320
|
export * from './controllers/info.controller'
|
|
319
321
|
export * from './services/settings/default-settings-provider.service'
|
package/src/interfaces.ts
CHANGED
|
@@ -70,6 +70,7 @@ export interface SettingDefinition<T = any> {
|
|
|
70
70
|
key: string;
|
|
71
71
|
value: T;
|
|
72
72
|
level: SettingLevel;
|
|
73
|
+
encrypted?: boolean;
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
// solid-core/settings/settings-provider.interface.ts
|
|
@@ -395,3 +396,18 @@ export interface AwsS3Config {
|
|
|
395
396
|
|
|
396
397
|
// Prevents inference so callers must provide explicit type arguments; reusable for other APIs.
|
|
397
398
|
export type NoInfer<T> = [T][T extends any ? 0 : never];
|
|
399
|
+
|
|
400
|
+
export type AuditEventType = 'insert' | 'update' | 'delete';
|
|
401
|
+
|
|
402
|
+
export interface AuditQueuePayload {
|
|
403
|
+
eventType: AuditEventType;
|
|
404
|
+
modelName: string;
|
|
405
|
+
entityId: string | number | null;
|
|
406
|
+
occurredAt: string;
|
|
407
|
+
after?: any;
|
|
408
|
+
before?: any;
|
|
409
|
+
updatedColumnNames?: string[];
|
|
410
|
+
userId?: number | null;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
|
|
@@ -4,7 +4,7 @@ import { DatabasePublisher } from 'src/services/queues/database-publisher.servic
|
|
|
4
4
|
import { MqMessageQueueService } from '../../services/mq-message-queue.service';
|
|
5
5
|
import { MqMessageService } from '../../services/mq-message.service';
|
|
6
6
|
import { QueuesModuleOptions } from "../../interfaces";
|
|
7
|
-
import { AuditQueuePayload } from '
|
|
7
|
+
import { AuditQueuePayload } from '../../interfaces';
|
|
8
8
|
import chatterQueueOptionsDatabase from './chatter-queue-options-database';
|
|
9
9
|
|
|
10
10
|
@Injectable()
|
|
@@ -6,7 +6,7 @@ import { MqMessageService } from '../../services/mq-message.service';
|
|
|
6
6
|
import { MqMessageQueueService } from '../../services/mq-message-queue.service';
|
|
7
7
|
import { QueuesModuleOptions } from "../../interfaces";
|
|
8
8
|
import { PollerService } from 'src/services/poller.service';
|
|
9
|
-
import { AuditQueuePayload } from '
|
|
9
|
+
import { AuditQueuePayload } from '../../interfaces';
|
|
10
10
|
import { ChatterMessageService } from 'src/services/chatter-message.service';
|
|
11
11
|
import chatterQueueOptionsDatabase from './chatter-queue-options-database';
|
|
12
12
|
|
|
@@ -4,21 +4,7 @@ import { RabbitMqPublisher } from 'src/services/queues/rabbitmq-publisher.servic
|
|
|
4
4
|
import chatterQueueOptions from './chatter-queue-options';
|
|
5
5
|
import { MqMessageQueueService } from '../../services/mq-message-queue.service';
|
|
6
6
|
import { MqMessageService } from '../../services/mq-message.service';
|
|
7
|
-
import { QueuesModuleOptions } from "../../interfaces";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export type AuditEventType = 'insert' | 'update' | 'delete';
|
|
11
|
-
|
|
12
|
-
export interface AuditQueuePayload {
|
|
13
|
-
eventType: AuditEventType;
|
|
14
|
-
modelName: string; // TypeORM entity class name (e.g. 'Order')
|
|
15
|
-
entityId: string | number | null;
|
|
16
|
-
occurredAt: string; // ISO timestamp, captured at event time
|
|
17
|
-
after?: any; // entity state after operation (insert/update)
|
|
18
|
-
before?: any; // entity state before operation (update/delete)
|
|
19
|
-
updatedColumnNames?: string[]; // propertyNames of changed columns (update only)
|
|
20
|
-
userId?: number | null; // active user captured at event time
|
|
21
|
-
}
|
|
7
|
+
import { AuditQueuePayload, QueuesModuleOptions } from "../../interfaces";
|
|
22
8
|
|
|
23
9
|
@Injectable()
|
|
24
10
|
export class ChatterQueuePublisherRabbitmq extends RabbitMqPublisher<AuditQueuePayload> {
|
|
@@ -6,7 +6,7 @@ import { MqMessageService } from '../../services/mq-message.service';
|
|
|
6
6
|
import { MqMessageQueueService } from '../../services/mq-message-queue.service';
|
|
7
7
|
import { QueuesModuleOptions } from "../../interfaces";
|
|
8
8
|
import chatterQueueOptions from './chatter-queue-options';
|
|
9
|
-
import { AuditQueuePayload } from '
|
|
9
|
+
import { AuditQueuePayload } from '../../interfaces';
|
|
10
10
|
import { ChatterMessageService } from 'src/services/chatter-message.service';
|
|
11
11
|
|
|
12
12
|
@Injectable()
|
|
@@ -6,7 +6,7 @@ import chatterQueueConfig from './chatter-queue-options-redis';
|
|
|
6
6
|
import { MqMessageService } from '../../services/mq-message.service';
|
|
7
7
|
import { MqMessageQueueService } from '../../services/mq-message-queue.service';
|
|
8
8
|
import { QueuesModuleOptions } from "../../interfaces";
|
|
9
|
-
import { AuditQueuePayload } from '
|
|
9
|
+
import { AuditQueuePayload } from '../../interfaces';
|
|
10
10
|
import { ChatterMessageService } from '../../services/chatter-message.service';
|
|
11
11
|
|
|
12
12
|
@Injectable()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { UserApiKey } from 'src/entities/user-api-key.entity';
|
|
3
|
+
import { RequestContextService } from 'src/services/request-context.service';
|
|
4
|
+
import { DataSource } from 'typeorm';
|
|
5
|
+
import { SecurityRuleRepository } from './security-rule.repository';
|
|
6
|
+
import { SolidBaseRepository } from './solid-base.repository';
|
|
7
|
+
|
|
8
|
+
@Injectable()
|
|
9
|
+
export class UserApiKeyRepository extends SolidBaseRepository<UserApiKey> {
|
|
10
|
+
constructor(
|
|
11
|
+
readonly dataSource: DataSource,
|
|
12
|
+
readonly requestContextService: RequestContextService,
|
|
13
|
+
readonly securityRuleRepository: SecurityRuleRepository,
|
|
14
|
+
) {
|
|
15
|
+
super(UserApiKey, dataSource, requestContextService, securityRuleRepository);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -2085,6 +2085,35 @@
|
|
|
2085
2085
|
"relationModelModuleName": "solid-core",
|
|
2086
2086
|
"isSystem": true
|
|
2087
2087
|
},
|
|
2088
|
+
{
|
|
2089
|
+
"name": "isAllowedToGenerateApiKeys",
|
|
2090
|
+
"displayName": "Is Allowed To Generate API Keys",
|
|
2091
|
+
"type": "boolean",
|
|
2092
|
+
"required": true,
|
|
2093
|
+
"unique": false,
|
|
2094
|
+
"index": false,
|
|
2095
|
+
"private": false,
|
|
2096
|
+
"encrypt": false,
|
|
2097
|
+
"defaultValue": "false",
|
|
2098
|
+
"isSystem": true,
|
|
2099
|
+
"enableAuditTracking": true
|
|
2100
|
+
},
|
|
2101
|
+
{
|
|
2102
|
+
"name": "apiKeys",
|
|
2103
|
+
"displayName": "API Keys",
|
|
2104
|
+
"type": "relation",
|
|
2105
|
+
"required": false,
|
|
2106
|
+
"unique": false,
|
|
2107
|
+
"index": false,
|
|
2108
|
+
"private": false,
|
|
2109
|
+
"encrypt": false,
|
|
2110
|
+
"relationType": "one-to-many",
|
|
2111
|
+
"relationCoModelSingularName": "userApiKey",
|
|
2112
|
+
"relationCoModelFieldName": "user",
|
|
2113
|
+
"relationCreateInverse": true,
|
|
2114
|
+
"relationModelModuleName": "solid-core",
|
|
2115
|
+
"isSystem": true
|
|
2116
|
+
},
|
|
2088
2117
|
{
|
|
2089
2118
|
"name": "passwordScheme",
|
|
2090
2119
|
"displayName": "Password Scheme",
|
|
@@ -2129,6 +2158,105 @@
|
|
|
2129
2158
|
}
|
|
2130
2159
|
]
|
|
2131
2160
|
},
|
|
2161
|
+
{
|
|
2162
|
+
"singularName": "userApiKey",
|
|
2163
|
+
"tableName": "ss_user_api_key",
|
|
2164
|
+
"pluralName": "userApiKeys",
|
|
2165
|
+
"displayName": "User API Key",
|
|
2166
|
+
"description": "API keys for programmatic server-to-server access",
|
|
2167
|
+
"dataSource": "default",
|
|
2168
|
+
"dataSourceType": "postgres",
|
|
2169
|
+
"userKeyFieldUserKey": "name",
|
|
2170
|
+
"isSystem": true,
|
|
2171
|
+
"fields": [
|
|
2172
|
+
{
|
|
2173
|
+
"name": "name",
|
|
2174
|
+
"displayName": "Name",
|
|
2175
|
+
"type": "shortText",
|
|
2176
|
+
"length": 512,
|
|
2177
|
+
"required": true,
|
|
2178
|
+
"unique": false,
|
|
2179
|
+
"index": false,
|
|
2180
|
+
"private": false,
|
|
2181
|
+
"encrypt": false,
|
|
2182
|
+
"isSystem": true
|
|
2183
|
+
},
|
|
2184
|
+
{
|
|
2185
|
+
"name": "hashedKey",
|
|
2186
|
+
"displayName": "Hashed Key",
|
|
2187
|
+
"type": "shortText",
|
|
2188
|
+
"length": 512,
|
|
2189
|
+
"required": true,
|
|
2190
|
+
"unique": true,
|
|
2191
|
+
"index": true,
|
|
2192
|
+
"private": true,
|
|
2193
|
+
"encrypt": false,
|
|
2194
|
+
"isSystem": true
|
|
2195
|
+
},
|
|
2196
|
+
{
|
|
2197
|
+
"name": "maskedKey",
|
|
2198
|
+
"displayName": "Masked Key",
|
|
2199
|
+
"type": "shortText",
|
|
2200
|
+
"length": 512,
|
|
2201
|
+
"required": true,
|
|
2202
|
+
"unique": false,
|
|
2203
|
+
"index": false,
|
|
2204
|
+
"private": false,
|
|
2205
|
+
"encrypt": false,
|
|
2206
|
+
"isSystem": true
|
|
2207
|
+
},
|
|
2208
|
+
{
|
|
2209
|
+
"name": "isActive",
|
|
2210
|
+
"displayName": "Is Active",
|
|
2211
|
+
"type": "boolean",
|
|
2212
|
+
"required": true,
|
|
2213
|
+
"unique": false,
|
|
2214
|
+
"index": false,
|
|
2215
|
+
"private": false,
|
|
2216
|
+
"encrypt": false,
|
|
2217
|
+
"defaultValue": "true",
|
|
2218
|
+
"isSystem": true
|
|
2219
|
+
},
|
|
2220
|
+
{
|
|
2221
|
+
"name": "expiresAt",
|
|
2222
|
+
"displayName": "Expires At",
|
|
2223
|
+
"type": "datetime",
|
|
2224
|
+
"required": false,
|
|
2225
|
+
"unique": false,
|
|
2226
|
+
"index": false,
|
|
2227
|
+
"private": false,
|
|
2228
|
+
"encrypt": false,
|
|
2229
|
+
"isSystem": true
|
|
2230
|
+
},
|
|
2231
|
+
{
|
|
2232
|
+
"name": "lastUsedAt",
|
|
2233
|
+
"displayName": "Last Used At",
|
|
2234
|
+
"type": "datetime",
|
|
2235
|
+
"required": false,
|
|
2236
|
+
"unique": false,
|
|
2237
|
+
"index": false,
|
|
2238
|
+
"private": false,
|
|
2239
|
+
"encrypt": false,
|
|
2240
|
+
"isSystem": true
|
|
2241
|
+
},
|
|
2242
|
+
{
|
|
2243
|
+
"name": "user",
|
|
2244
|
+
"displayName": "User",
|
|
2245
|
+
"type": "relation",
|
|
2246
|
+
"required": true,
|
|
2247
|
+
"unique": false,
|
|
2248
|
+
"index": false,
|
|
2249
|
+
"private": false,
|
|
2250
|
+
"encrypt": false,
|
|
2251
|
+
"relationType": "many-to-one",
|
|
2252
|
+
"relationCoModelSingularName": "user",
|
|
2253
|
+
"relationCoModelFieldName": "apiKeys",
|
|
2254
|
+
"relationCreateInverse": true,
|
|
2255
|
+
"relationModelModuleName": "solid-core",
|
|
2256
|
+
"isSystem": true
|
|
2257
|
+
}
|
|
2258
|
+
]
|
|
2259
|
+
},
|
|
2132
2260
|
{
|
|
2133
2261
|
"singularName": "userActivityHistory",
|
|
2134
2262
|
"tableName": "ss_user_activity_history",
|
|
@@ -5490,7 +5618,7 @@
|
|
|
5490
5618
|
"private": false,
|
|
5491
5619
|
"encrypt": false,
|
|
5492
5620
|
"isSystem": true,
|
|
5493
|
-
"selectionStaticValues": ["active", "completed", "failed", "cancelled"],
|
|
5621
|
+
"selectionStaticValues": ["active:Active", "completed:Completed", "failed:Failed", "cancelled:Cancelled"],
|
|
5494
5622
|
"selectionValueType": "string"
|
|
5495
5623
|
},
|
|
5496
5624
|
{
|
|
@@ -5627,15 +5755,15 @@
|
|
|
5627
5755
|
"encrypt": false,
|
|
5628
5756
|
"isSystem": true,
|
|
5629
5757
|
"selectionStaticValues": [
|
|
5630
|
-
"user_message",
|
|
5631
|
-
"assistant_message",
|
|
5632
|
-
"tool_use",
|
|
5633
|
-
"tool_result",
|
|
5634
|
-
"system_prompt",
|
|
5635
|
-
"thinking",
|
|
5636
|
-
"error",
|
|
5637
|
-
"session_start",
|
|
5638
|
-
"session_end"
|
|
5758
|
+
"user_message:User Message",
|
|
5759
|
+
"assistant_message:Assistant Message",
|
|
5760
|
+
"tool_use:Tool Use",
|
|
5761
|
+
"tool_result:Tool Result",
|
|
5762
|
+
"system_prompt:System Prompt",
|
|
5763
|
+
"thinking:Thinking",
|
|
5764
|
+
"error:Error",
|
|
5765
|
+
"session_start:Session Start",
|
|
5766
|
+
"session_end:Session End"
|
|
5639
5767
|
],
|
|
5640
5768
|
"selectionValueType": "string"
|
|
5641
5769
|
},
|
|
@@ -13601,9 +13729,9 @@
|
|
|
13601
13729
|
"pagination": true,
|
|
13602
13730
|
"pageSizeOptions": [10, 25, 50],
|
|
13603
13731
|
"enableGlobalSearch": true,
|
|
13604
|
-
"create":
|
|
13732
|
+
"create": true,
|
|
13605
13733
|
"edit": true,
|
|
13606
|
-
"delete":
|
|
13734
|
+
"delete": true
|
|
13607
13735
|
},
|
|
13608
13736
|
"children": [
|
|
13609
13737
|
{ "type": "field", "attrs": { "name": "sessionId", "isSearchable": true } },
|
|
@@ -13659,9 +13787,7 @@
|
|
|
13659
13787
|
{ "type": "field", "attrs": { "name": "totalSteps" } },
|
|
13660
13788
|
{ "type": "field", "attrs": { "name": "totalCost" } },
|
|
13661
13789
|
{ "type": "field", "attrs": { "name": "totalInputTokens" } },
|
|
13662
|
-
{ "type": "field", "attrs": { "name": "totalOutputTokens" } }
|
|
13663
|
-
{ "type": "field", "attrs": { "name": "createdAt" } },
|
|
13664
|
-
{ "type": "field", "attrs": { "name": "updatedAt" } }
|
|
13790
|
+
{ "type": "field", "attrs": { "name": "totalOutputTokens" } }
|
|
13665
13791
|
]
|
|
13666
13792
|
}
|
|
13667
13793
|
]
|
|
@@ -13697,9 +13823,9 @@
|
|
|
13697
13823
|
"pagination": true,
|
|
13698
13824
|
"pageSizeOptions": [10, 25, 50],
|
|
13699
13825
|
"enableGlobalSearch": true,
|
|
13700
|
-
"create":
|
|
13701
|
-
"edit":
|
|
13702
|
-
"delete":
|
|
13826
|
+
"create": true,
|
|
13827
|
+
"edit": true,
|
|
13828
|
+
"delete": true
|
|
13703
13829
|
},
|
|
13704
13830
|
"children": [
|
|
13705
13831
|
{ "type": "field", "attrs": { "name": "id" } },
|
|
@@ -13760,8 +13886,7 @@
|
|
|
13760
13886
|
{ "type": "field", "attrs": { "name": "cost" } },
|
|
13761
13887
|
{ "type": "field", "attrs": { "name": "inputTokens" } },
|
|
13762
13888
|
{ "type": "field", "attrs": { "name": "outputTokens" } },
|
|
13763
|
-
{ "type": "field", "attrs": { "name": "toolReturncode" } }
|
|
13764
|
-
{ "type": "field", "attrs": { "name": "createdAt" } }
|
|
13889
|
+
{ "type": "field", "attrs": { "name": "toolReturncode" } }
|
|
13765
13890
|
]
|
|
13766
13891
|
}
|
|
13767
13892
|
]
|