@pawells/nestjs-auth 1.0.0-dev.4c8c698
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/LICENSE +21 -0
- package/README.md +602 -0
- package/build/LICENSE +21 -0
- package/build/README.md +602 -0
- package/build/admin/client/client.d.ts +82 -0
- package/build/admin/client/client.d.ts.map +1 -0
- package/build/admin/client/client.js +157 -0
- package/build/admin/client/client.js.map +1 -0
- package/build/admin/client/errors/base-error.d.ts +58 -0
- package/build/admin/client/errors/base-error.d.ts.map +1 -0
- package/build/admin/client/errors/base-error.js +100 -0
- package/build/admin/client/errors/base-error.js.map +1 -0
- package/build/admin/client/errors/index.d.ts +2 -0
- package/build/admin/client/errors/index.d.ts.map +1 -0
- package/build/admin/client/errors/index.js +2 -0
- package/build/admin/client/errors/index.js.map +1 -0
- package/build/admin/client/index.d.ts +6 -0
- package/build/admin/client/index.d.ts.map +1 -0
- package/build/admin/client/index.js +11 -0
- package/build/admin/client/index.js.map +1 -0
- package/build/admin/client/services/authentication.service.d.ts +54 -0
- package/build/admin/client/services/authentication.service.d.ts.map +1 -0
- package/build/admin/client/services/authentication.service.js +99 -0
- package/build/admin/client/services/authentication.service.js.map +1 -0
- package/build/admin/client/services/base-service.d.ts +39 -0
- package/build/admin/client/services/base-service.d.ts.map +1 -0
- package/build/admin/client/services/base-service.js +107 -0
- package/build/admin/client/services/base-service.js.map +1 -0
- package/build/admin/client/services/client.service.d.ts +86 -0
- package/build/admin/client/services/client.service.d.ts.map +1 -0
- package/build/admin/client/services/client.service.js +193 -0
- package/build/admin/client/services/client.service.js.map +1 -0
- package/build/admin/client/services/event.service.d.ts +84 -0
- package/build/admin/client/services/event.service.d.ts.map +1 -0
- package/build/admin/client/services/event.service.js +155 -0
- package/build/admin/client/services/event.service.js.map +1 -0
- package/build/admin/client/services/federated-identity.service.d.ts +89 -0
- package/build/admin/client/services/federated-identity.service.d.ts.map +1 -0
- package/build/admin/client/services/federated-identity.service.js +120 -0
- package/build/admin/client/services/federated-identity.service.js.map +1 -0
- package/build/admin/client/services/group.service.d.ts +52 -0
- package/build/admin/client/services/group.service.d.ts.map +1 -0
- package/build/admin/client/services/group.service.js +105 -0
- package/build/admin/client/services/group.service.js.map +1 -0
- package/build/admin/client/services/identity-provider.service.d.ts +47 -0
- package/build/admin/client/services/identity-provider.service.d.ts.map +1 -0
- package/build/admin/client/services/identity-provider.service.js +86 -0
- package/build/admin/client/services/identity-provider.service.js.map +1 -0
- package/build/admin/client/services/index.d.ts +11 -0
- package/build/admin/client/services/index.d.ts.map +1 -0
- package/build/admin/client/services/index.js +11 -0
- package/build/admin/client/services/index.js.map +1 -0
- package/build/admin/client/services/realm.service.d.ts +41 -0
- package/build/admin/client/services/realm.service.d.ts.map +1 -0
- package/build/admin/client/services/realm.service.js +80 -0
- package/build/admin/client/services/realm.service.js.map +1 -0
- package/build/admin/client/services/role.service.d.ts +45 -0
- package/build/admin/client/services/role.service.d.ts.map +1 -0
- package/build/admin/client/services/role.service.js +92 -0
- package/build/admin/client/services/role.service.js.map +1 -0
- package/build/admin/client/services/user.service.d.ts +84 -0
- package/build/admin/client/services/user.service.d.ts.map +1 -0
- package/build/admin/client/services/user.service.js +216 -0
- package/build/admin/client/services/user.service.js.map +1 -0
- package/build/admin/client/types/config.types.d.ts +59 -0
- package/build/admin/client/types/config.types.d.ts.map +1 -0
- package/build/admin/client/types/config.types.js +13 -0
- package/build/admin/client/types/config.types.js.map +1 -0
- package/build/admin/client/types/event.types.d.ts +176 -0
- package/build/admin/client/types/event.types.d.ts.map +1 -0
- package/build/admin/client/types/event.types.js +2 -0
- package/build/admin/client/types/event.types.js.map +1 -0
- package/build/admin/client/types/index.d.ts +4 -0
- package/build/admin/client/types/index.d.ts.map +1 -0
- package/build/admin/client/types/index.js +4 -0
- package/build/admin/client/types/index.js.map +1 -0
- package/build/admin/client/types/keycloak.types.d.ts +169 -0
- package/build/admin/client/types/keycloak.types.d.ts.map +1 -0
- package/build/admin/client/types/keycloak.types.js +2 -0
- package/build/admin/client/types/keycloak.types.js.map +1 -0
- package/build/admin/client/utils/index.d.ts +2 -0
- package/build/admin/client/utils/index.d.ts.map +1 -0
- package/build/admin/client/utils/index.js +2 -0
- package/build/admin/client/utils/index.js.map +1 -0
- package/build/admin/client/utils/retry.d.ts +40 -0
- package/build/admin/client/utils/retry.d.ts.map +1 -0
- package/build/admin/client/utils/retry.js +72 -0
- package/build/admin/client/utils/retry.js.map +1 -0
- package/build/admin/config/keycloak.config.d.ts +33 -0
- package/build/admin/config/keycloak.config.d.ts.map +1 -0
- package/build/admin/config/keycloak.config.js +2 -0
- package/build/admin/config/keycloak.config.js.map +1 -0
- package/build/admin/config/keycloak.defaults.d.ts +11 -0
- package/build/admin/config/keycloak.defaults.d.ts.map +1 -0
- package/build/admin/config/keycloak.defaults.js +60 -0
- package/build/admin/config/keycloak.defaults.js.map +1 -0
- package/build/admin/health/keycloak.health.d.ts +13 -0
- package/build/admin/health/keycloak.health.d.ts.map +1 -0
- package/build/admin/health/keycloak.health.js +54 -0
- package/build/admin/health/keycloak.health.js.map +1 -0
- package/build/admin/index.d.ts +10 -0
- package/build/admin/index.d.ts.map +1 -0
- package/build/admin/index.js +9 -0
- package/build/admin/index.js.map +1 -0
- package/build/admin/keycloak-admin.interfaces.d.ts +45 -0
- package/build/admin/keycloak-admin.interfaces.d.ts.map +1 -0
- package/build/admin/keycloak-admin.interfaces.js +2 -0
- package/build/admin/keycloak-admin.interfaces.js.map +1 -0
- package/build/admin/keycloak-admin.module.d.ts +23 -0
- package/build/admin/keycloak-admin.module.d.ts.map +1 -0
- package/build/admin/keycloak-admin.module.js +101 -0
- package/build/admin/keycloak-admin.module.js.map +1 -0
- package/build/admin/keycloak.constants.d.ts +16 -0
- package/build/admin/keycloak.constants.d.ts.map +1 -0
- package/build/admin/keycloak.constants.js +16 -0
- package/build/admin/keycloak.constants.js.map +1 -0
- package/build/admin/permissions/index.d.ts +2 -0
- package/build/admin/permissions/index.d.ts.map +1 -0
- package/build/admin/permissions/index.js +2 -0
- package/build/admin/permissions/index.js.map +1 -0
- package/build/admin/permissions/keycloak-admin.permissions.d.ts +45 -0
- package/build/admin/permissions/keycloak-admin.permissions.d.ts.map +1 -0
- package/build/admin/permissions/keycloak-admin.permissions.js +68 -0
- package/build/admin/permissions/keycloak-admin.permissions.js.map +1 -0
- package/build/admin/services/keycloak-admin.service.d.ts +64 -0
- package/build/admin/services/keycloak-admin.service.d.ts.map +1 -0
- package/build/admin/services/keycloak-admin.service.js +152 -0
- package/build/admin/services/keycloak-admin.service.js.map +1 -0
- package/build/decorators/auth-decorators.d.ts +217 -0
- package/build/decorators/auth-decorators.d.ts.map +1 -0
- package/build/decorators/auth-decorators.js +251 -0
- package/build/decorators/auth-decorators.js.map +1 -0
- package/build/decorators/context-utils.d.ts +101 -0
- package/build/decorators/context-utils.d.ts.map +1 -0
- package/build/decorators/context-utils.js +178 -0
- package/build/decorators/context-utils.js.map +1 -0
- package/build/decorators/graphql-auth-decorators.d.ts +144 -0
- package/build/decorators/graphql-auth-decorators.d.ts.map +1 -0
- package/build/decorators/graphql-auth-decorators.js +152 -0
- package/build/decorators/graphql-auth-decorators.js.map +1 -0
- package/build/decorators/index.d.ts +5 -0
- package/build/decorators/index.d.ts.map +1 -0
- package/build/decorators/index.js +4 -0
- package/build/decorators/index.js.map +1 -0
- package/build/guards/index.d.ts +4 -0
- package/build/guards/index.d.ts.map +1 -0
- package/build/guards/index.js +4 -0
- package/build/guards/index.js.map +1 -0
- package/build/guards/jwt-auth.guard.d.ts +52 -0
- package/build/guards/jwt-auth.guard.d.ts.map +1 -0
- package/build/guards/jwt-auth.guard.js +97 -0
- package/build/guards/jwt-auth.guard.js.map +1 -0
- package/build/guards/permission.guard.d.ts +37 -0
- package/build/guards/permission.guard.d.ts.map +1 -0
- package/build/guards/permission.guard.js +73 -0
- package/build/guards/permission.guard.js.map +1 -0
- package/build/guards/role.guard.d.ts +33 -0
- package/build/guards/role.guard.d.ts.map +1 -0
- package/build/guards/role.guard.js +69 -0
- package/build/guards/role.guard.js.map +1 -0
- package/build/index.d.ts +92 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +98 -0
- package/build/index.js.map +1 -0
- package/build/keycloak/index.d.ts +7 -0
- package/build/keycloak/index.d.ts.map +1 -0
- package/build/keycloak/index.js +5 -0
- package/build/keycloak/index.js.map +1 -0
- package/build/keycloak/keycloak.constants.d.ts +2 -0
- package/build/keycloak/keycloak.constants.d.ts.map +1 -0
- package/build/keycloak/keycloak.constants.js +2 -0
- package/build/keycloak/keycloak.constants.js.map +1 -0
- package/build/keycloak/keycloak.interfaces.d.ts +12 -0
- package/build/keycloak/keycloak.interfaces.d.ts.map +1 -0
- package/build/keycloak/keycloak.interfaces.js +2 -0
- package/build/keycloak/keycloak.interfaces.js.map +1 -0
- package/build/keycloak/keycloak.module.d.ts +56 -0
- package/build/keycloak/keycloak.module.d.ts.map +1 -0
- package/build/keycloak/keycloak.module.js +104 -0
- package/build/keycloak/keycloak.module.js.map +1 -0
- package/build/keycloak/keycloak.types.d.ts +60 -0
- package/build/keycloak/keycloak.types.d.ts.map +1 -0
- package/build/keycloak/keycloak.types.js +2 -0
- package/build/keycloak/keycloak.types.js.map +1 -0
- package/build/keycloak/services/jwks-cache.service.d.ts +64 -0
- package/build/keycloak/services/jwks-cache.service.d.ts.map +1 -0
- package/build/keycloak/services/jwks-cache.service.js +176 -0
- package/build/keycloak/services/jwks-cache.service.js.map +1 -0
- package/build/keycloak/services/keycloak-token-validation.service.d.ts +88 -0
- package/build/keycloak/services/keycloak-token-validation.service.d.ts.map +1 -0
- package/build/keycloak/services/keycloak-token-validation.service.js +243 -0
- package/build/keycloak/services/keycloak-token-validation.service.js.map +1 -0
- package/build/package.json +72 -0
- package/package.json +93 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var KeycloakAdminService_1;
|
|
11
|
+
import { Injectable } from '@nestjs/common';
|
|
12
|
+
import { ModuleRef } from '@nestjs/core';
|
|
13
|
+
import { KeycloakClient } from '../client/client.js';
|
|
14
|
+
import { AppLogger, getErrorMessage } from '@pawells/nestjs-shared/common';
|
|
15
|
+
import { KEYCLOAK_ADMIN_CONFIG_TOKEN } from '../keycloak.constants.js';
|
|
16
|
+
import { KEYCLOAK_DEFAULT_SCOPES } from '../permissions/keycloak-admin.permissions.js';
|
|
17
|
+
let KeycloakAdminService = KeycloakAdminService_1 = class KeycloakAdminService {
|
|
18
|
+
logger;
|
|
19
|
+
client = null;
|
|
20
|
+
grantedScopes = new Set(KEYCLOAK_DEFAULT_SCOPES);
|
|
21
|
+
Module;
|
|
22
|
+
get Config() {
|
|
23
|
+
return this.Module.get(KEYCLOAK_ADMIN_CONFIG_TOKEN, { strict: false });
|
|
24
|
+
}
|
|
25
|
+
get AppLogger() {
|
|
26
|
+
return this.Module.get(AppLogger);
|
|
27
|
+
}
|
|
28
|
+
constructor(module) {
|
|
29
|
+
this.Module = module;
|
|
30
|
+
this.logger = new AppLogger(undefined, KeycloakAdminService_1.name);
|
|
31
|
+
}
|
|
32
|
+
async onModuleInit() {
|
|
33
|
+
if (!this.Config.enabled) {
|
|
34
|
+
this.logger.info('Keycloak admin client is disabled, skipping initialization');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
this.logger.info('Initializing Keycloak admin client...');
|
|
39
|
+
// Build and validate permission scopes
|
|
40
|
+
const scopes = this.Config.permissions ?? [...KEYCLOAK_DEFAULT_SCOPES];
|
|
41
|
+
this.grantedScopes = new Set(scopes);
|
|
42
|
+
if (!this.Config.permissions) {
|
|
43
|
+
this.logger.warn('KeycloakAdminModule: no permissions configured — defaulting to read-only scopes. ' +
|
|
44
|
+
'To grant write access, set the permissions array in KeycloakAdminModule.forRoot() config.');
|
|
45
|
+
}
|
|
46
|
+
const { type: _type, ...credentialsWithoutType } = this.Config.credentials;
|
|
47
|
+
this.client = new KeycloakClient({
|
|
48
|
+
baseUrl: this.Config.baseUrl,
|
|
49
|
+
realmName: this.Config.realmName,
|
|
50
|
+
credentials: credentialsWithoutType,
|
|
51
|
+
timeout: this.Config.timeout,
|
|
52
|
+
retry: this.Config.retry,
|
|
53
|
+
}, this.grantedScopes);
|
|
54
|
+
await this.client.authenticate();
|
|
55
|
+
this.logger.info('Keycloak admin client initialized successfully');
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
this.logger.error(`Failed to initialize Keycloak admin client: ${getErrorMessage(error)}`);
|
|
59
|
+
// Re-throw if Keycloak is enabled, so startup fails loudly instead of silently
|
|
60
|
+
if (this.Config.enabled) {
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
getClient() {
|
|
66
|
+
return this.client;
|
|
67
|
+
}
|
|
68
|
+
isEnabled() {
|
|
69
|
+
return this.Config.enabled;
|
|
70
|
+
}
|
|
71
|
+
isAuthenticated() {
|
|
72
|
+
return this.client?.isAuthenticated() ?? false;
|
|
73
|
+
}
|
|
74
|
+
// Proxy methods to client services
|
|
75
|
+
get users() {
|
|
76
|
+
if (!this.client)
|
|
77
|
+
throw new Error('Keycloak client not initialized');
|
|
78
|
+
return this.client.Users;
|
|
79
|
+
}
|
|
80
|
+
get realms() {
|
|
81
|
+
if (!this.client)
|
|
82
|
+
throw new Error('Keycloak client not initialized');
|
|
83
|
+
return this.client.Realms;
|
|
84
|
+
}
|
|
85
|
+
get clients() {
|
|
86
|
+
if (!this.client)
|
|
87
|
+
throw new Error('Keycloak client not initialized');
|
|
88
|
+
return this.client.Clients;
|
|
89
|
+
}
|
|
90
|
+
get roles() {
|
|
91
|
+
if (!this.client)
|
|
92
|
+
throw new Error('Keycloak client not initialized');
|
|
93
|
+
return this.client.Roles;
|
|
94
|
+
}
|
|
95
|
+
get groups() {
|
|
96
|
+
if (!this.client)
|
|
97
|
+
throw new Error('Keycloak client not initialized');
|
|
98
|
+
return this.client.Groups;
|
|
99
|
+
}
|
|
100
|
+
get identityProviders() {
|
|
101
|
+
if (!this.client)
|
|
102
|
+
throw new Error('Keycloak client not initialized');
|
|
103
|
+
return this.client.IdentityProviders;
|
|
104
|
+
}
|
|
105
|
+
get authentication() {
|
|
106
|
+
if (!this.client)
|
|
107
|
+
throw new Error('Keycloak client not initialized');
|
|
108
|
+
return this.client.Authentication;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get the federated identity service for managing identity provider links
|
|
112
|
+
*
|
|
113
|
+
* Provides methods to list, link, and unlink external identity providers for users.
|
|
114
|
+
*
|
|
115
|
+
* @returns FederatedIdentityService instance
|
|
116
|
+
* @throws {Error} If Keycloak client is not initialized
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* const links = await keycloakAdmin.federatedIdentity.list(userId);
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
get federatedIdentity() {
|
|
124
|
+
if (!this.client)
|
|
125
|
+
throw new Error('Keycloak client not initialized');
|
|
126
|
+
return this.client.FederatedIdentities;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get the event service for querying realm events
|
|
130
|
+
*
|
|
131
|
+
* Provides methods to query administrative and access events for audit logging and monitoring.
|
|
132
|
+
*
|
|
133
|
+
* @returns EventService instance
|
|
134
|
+
* @throws {Error} If Keycloak client is not initialized
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* const events = await keycloakAdmin.events.getAdminEvents({ max: 100 });
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
get events() {
|
|
142
|
+
if (!this.client)
|
|
143
|
+
throw new Error('Keycloak client not initialized');
|
|
144
|
+
return this.client.Events;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
KeycloakAdminService = KeycloakAdminService_1 = __decorate([
|
|
148
|
+
Injectable(),
|
|
149
|
+
__metadata("design:paramtypes", [ModuleRef])
|
|
150
|
+
], KeycloakAdminService);
|
|
151
|
+
export { KeycloakAdminService };
|
|
152
|
+
//# sourceMappingURL=keycloak-admin.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keycloak-admin.service.js","sourceRoot":"","sources":["../../../src/admin/services/keycloak-admin.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { ContextOptions } from './context-utils.js';
|
|
2
|
+
/**
|
|
3
|
+
* Authentication Decorators for NestJS
|
|
4
|
+
*
|
|
5
|
+
* This module provides base authentication decorators that work across different
|
|
6
|
+
* NestJS contexts (HTTP, GraphQL, WebSockets). These decorators use standardized
|
|
7
|
+
* metadata keys and can be extended by context-specific packages.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Metadata key for public access routes/resolvers
|
|
13
|
+
* Used by guards to determine if authentication is required
|
|
14
|
+
*/
|
|
15
|
+
export declare const IS_PUBLIC_KEY = "isPublic";
|
|
16
|
+
/**
|
|
17
|
+
* Metadata key for role-based access control
|
|
18
|
+
* Used by guards to check user permissions
|
|
19
|
+
*/
|
|
20
|
+
export declare const ROLES_KEY = "roles";
|
|
21
|
+
/**
|
|
22
|
+
* Metadata key for permission-based access control
|
|
23
|
+
* Used by guards to check user permissions
|
|
24
|
+
*/
|
|
25
|
+
export declare const PERMISSIONS_KEY = "permissions";
|
|
26
|
+
/**
|
|
27
|
+
* Decorator to mark routes/resolvers as public (no authentication required)
|
|
28
|
+
*
|
|
29
|
+
* This decorator sets the IS_PUBLIC_KEY metadata to true, signaling to
|
|
30
|
+
* authentication guards that the decorated endpoint should be accessible
|
|
31
|
+
* without authentication.
|
|
32
|
+
*
|
|
33
|
+
* @returns Method decorator that marks the endpoint as public
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* @Public()
|
|
38
|
+
* @Get('health')
|
|
39
|
+
* checkHealth() {
|
|
40
|
+
* return { status: 'ok' };
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @example GraphQL
|
|
45
|
+
* ```typescript
|
|
46
|
+
* @Public()
|
|
47
|
+
* @Query(() => String)
|
|
48
|
+
* async getHealth(): Promise<string> {
|
|
49
|
+
* return 'OK';
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare const Public: () => MethodDecorator;
|
|
54
|
+
/**
|
|
55
|
+
* Decorator to mark routes/resolvers as requiring authentication
|
|
56
|
+
*
|
|
57
|
+
* This decorator sets the IS_PUBLIC_KEY metadata to false, ensuring that
|
|
58
|
+
* authentication guards will require valid credentials for the decorated endpoint.
|
|
59
|
+
*
|
|
60
|
+
* @returns Method decorator that marks the endpoint as requiring authentication
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* @Auth()
|
|
65
|
+
* @Get('profile')
|
|
66
|
+
* getProfile() {
|
|
67
|
+
* // This endpoint requires authentication
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example GraphQL
|
|
72
|
+
* ```typescript
|
|
73
|
+
* @Auth()
|
|
74
|
+
* @Query(() => User)
|
|
75
|
+
* async getCurrentUser(@CurrentUser() user: User): Promise<User> {
|
|
76
|
+
* return user;
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export declare const Auth: () => MethodDecorator;
|
|
81
|
+
/**
|
|
82
|
+
* Decorator to specify required roles for routes/resolvers
|
|
83
|
+
*
|
|
84
|
+
* This decorator sets the ROLES_KEY metadata with an array of required roles.
|
|
85
|
+
* Role guards will check that the authenticated user has at least one of the
|
|
86
|
+
* specified roles before allowing access.
|
|
87
|
+
*
|
|
88
|
+
* @param roles - Array of role names required for access
|
|
89
|
+
* @returns Method decorator that specifies role requirements
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* @Roles('admin', 'moderator')
|
|
94
|
+
* @Post('admin-action')
|
|
95
|
+
* adminAction() {
|
|
96
|
+
* // Only users with 'admin' or 'moderator' roles can access
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* @example GraphQL
|
|
101
|
+
* ```typescript
|
|
102
|
+
* @Roles('admin')
|
|
103
|
+
* @Mutation(() => User)
|
|
104
|
+
* async updateUser(@Args('input') input: UpdateUserInput): Promise<User> {
|
|
105
|
+
* // Only admin users can update other users
|
|
106
|
+
* }
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export declare const Roles: (...roles: string[]) => MethodDecorator;
|
|
110
|
+
/**
|
|
111
|
+
* Decorator to specify required permissions for routes/resolvers
|
|
112
|
+
*
|
|
113
|
+
* This decorator sets the PERMISSIONS_KEY metadata with an array of required permissions.
|
|
114
|
+
* Permission guards check that the authenticated user has at least one of the specified
|
|
115
|
+
* permissions (OR logic). Uses roles-as-permissions semantics — permission strings are
|
|
116
|
+
* matched against user role names.
|
|
117
|
+
*
|
|
118
|
+
* @param permissions - Array of permission names required for access
|
|
119
|
+
* @returns Method decorator that specifies permission requirements
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* @Permissions('user.create', 'user.update')
|
|
124
|
+
* @Post('users')
|
|
125
|
+
* createUser(@Body() data: CreateUserDto) {
|
|
126
|
+
* // Only users with 'user.create' OR 'user.update' role can access (roles-as-permissions)
|
|
127
|
+
* }
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* @example GraphQL
|
|
131
|
+
* ```typescript
|
|
132
|
+
* @Permissions('user.delete')
|
|
133
|
+
* @Mutation(() => Boolean)
|
|
134
|
+
* async deleteUser(@Args('id') id: string): Promise<boolean> {
|
|
135
|
+
* // Only users with 'user.delete' role can delete users
|
|
136
|
+
* }
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
export declare const Permissions: (...permissions: string[]) => MethodDecorator;
|
|
140
|
+
export type { ContextOptions } from './context-utils.js';
|
|
141
|
+
export { detectContextType, extractRequestFromContext, extractUserFromContext, extractAuthTokenFromContext } from './context-utils.js';
|
|
142
|
+
/**
|
|
143
|
+
* Parameter decorator to extract the current authenticated user
|
|
144
|
+
*
|
|
145
|
+
* This decorator injects the authenticated user object from the request context
|
|
146
|
+
* into method parameters. The user object is typically populated by authentication
|
|
147
|
+
* guards during the request processing pipeline.
|
|
148
|
+
*
|
|
149
|
+
* Supports both HTTP and GraphQL contexts with automatic detection or explicit specification.
|
|
150
|
+
*
|
|
151
|
+
* @param property - Optional property path to extract from the user object (e.g., 'id', 'profile.name')
|
|
152
|
+
* @param options - Context options for controlling extraction behavior
|
|
153
|
+
* @returns Parameter decorator that injects the current user or user property
|
|
154
|
+
*
|
|
155
|
+
* @example HTTP context (auto-detected)
|
|
156
|
+
* ```typescript
|
|
157
|
+
* @Get('profile')
|
|
158
|
+
* getProfile(@CurrentUser() user: User) {
|
|
159
|
+
* return user;
|
|
160
|
+
* }
|
|
161
|
+
* ```
|
|
162
|
+
*
|
|
163
|
+
* @example With property access
|
|
164
|
+
* ```typescript
|
|
165
|
+
* @Get('profile')
|
|
166
|
+
* getProfile(@CurrentUser('id') userId: string) {
|
|
167
|
+
* return this.userService.findById(userId);
|
|
168
|
+
* }
|
|
169
|
+
* ```
|
|
170
|
+
*
|
|
171
|
+
* @example GraphQL context (explicit)
|
|
172
|
+
* ```typescript
|
|
173
|
+
* @Query(() => User)
|
|
174
|
+
* async getCurrentUser(@CurrentUser(undefined, { contextType: 'graphql' }) user: User): Promise<User> {
|
|
175
|
+
* return user;
|
|
176
|
+
* }
|
|
177
|
+
* ```
|
|
178
|
+
*
|
|
179
|
+
* @example Auto-detect context
|
|
180
|
+
* ```typescript
|
|
181
|
+
* @UseGuards(AuthGuard)
|
|
182
|
+
* getData(@CurrentUser() user: User) {
|
|
183
|
+
* // Works in both HTTP and GraphQL contexts
|
|
184
|
+
* }
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
export declare function CurrentUser(property?: string, options?: ContextOptions): ParameterDecorator;
|
|
188
|
+
/**
|
|
189
|
+
* Parameter decorator to extract the authorization token from request headers
|
|
190
|
+
*
|
|
191
|
+
* This decorator injects the raw authorization token from the request headers
|
|
192
|
+
* into method parameters. Useful for custom token validation or when you need
|
|
193
|
+
* access to the raw token string.
|
|
194
|
+
*
|
|
195
|
+
* Supports both HTTP and GraphQL contexts with automatic detection or explicit specification.
|
|
196
|
+
*
|
|
197
|
+
* @param options - Context options for controlling extraction behavior
|
|
198
|
+
* @returns Parameter decorator that injects the authorization token
|
|
199
|
+
*
|
|
200
|
+
* @example HTTP context (auto-detected)
|
|
201
|
+
* ```typescript
|
|
202
|
+
* @Get('validate-token')
|
|
203
|
+
* validateToken(@AuthToken() token: string) {
|
|
204
|
+
* return this.authService.validateToken(token);
|
|
205
|
+
* }
|
|
206
|
+
* ```
|
|
207
|
+
*
|
|
208
|
+
* @example GraphQL context (explicit)
|
|
209
|
+
* ```typescript
|
|
210
|
+
* @Query(() => Boolean)
|
|
211
|
+
* async validateToken(@AuthToken({ contextType: 'graphql' }) token: string): Promise<boolean> {
|
|
212
|
+
* return this.authService.validateToken(token);
|
|
213
|
+
* }
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
export declare function AuthToken(options?: ContextOptions): ParameterDecorator;
|
|
217
|
+
//# sourceMappingURL=auth-decorators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-decorators.d.ts","sourceRoot":"","sources":["../../src/decorators/auth-decorators.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAA6B,MAAM,oBAAoB,CAAC;AAE/E;;;;;;;;GAQG;AAEH;;;GAGG;AACH,eAAO,MAAM,aAAa,aAAa,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,SAAS,UAAU,CAAC;AAEjC;;;GAGG;AACH,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,MAAM,QAAO,eAGxB,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,IAAI,QAAO,eAGtB,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,KAAK,GAAI,GAAG,OAAO,MAAM,EAAE,KAAG,eAGzC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,WAAW,GAAI,GAAG,aAAa,MAAM,EAAE,KAAG,eAGrD,CAAC;AAGH,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEvI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,kBAAkB,CAa3F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,kBAAkB,CAkBtE"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { createParamDecorator } from '@nestjs/common';
|
|
2
|
+
import { createConditionalDecorator } from '@pawells/nestjs-shared/common';
|
|
3
|
+
import { ExtractRequestFromContext } from './context-utils.js';
|
|
4
|
+
/**
|
|
5
|
+
* Authentication Decorators for NestJS
|
|
6
|
+
*
|
|
7
|
+
* This module provides base authentication decorators that work across different
|
|
8
|
+
* NestJS contexts (HTTP, GraphQL, WebSockets). These decorators use standardized
|
|
9
|
+
* metadata keys and can be extended by context-specific packages.
|
|
10
|
+
*
|
|
11
|
+
* @packageDocumentation
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Metadata key for public access routes/resolvers
|
|
15
|
+
* Used by guards to determine if authentication is required
|
|
16
|
+
*/
|
|
17
|
+
export const IS_PUBLIC_KEY = 'isPublic';
|
|
18
|
+
/**
|
|
19
|
+
* Metadata key for role-based access control
|
|
20
|
+
* Used by guards to check user permissions
|
|
21
|
+
*/
|
|
22
|
+
export const ROLES_KEY = 'roles';
|
|
23
|
+
/**
|
|
24
|
+
* Metadata key for permission-based access control
|
|
25
|
+
* Used by guards to check user permissions
|
|
26
|
+
*/
|
|
27
|
+
export const PERMISSIONS_KEY = 'permissions';
|
|
28
|
+
/**
|
|
29
|
+
* Decorator to mark routes/resolvers as public (no authentication required)
|
|
30
|
+
*
|
|
31
|
+
* This decorator sets the IS_PUBLIC_KEY metadata to true, signaling to
|
|
32
|
+
* authentication guards that the decorated endpoint should be accessible
|
|
33
|
+
* without authentication.
|
|
34
|
+
*
|
|
35
|
+
* @returns Method decorator that marks the endpoint as public
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* @Public()
|
|
40
|
+
* @Get('health')
|
|
41
|
+
* checkHealth() {
|
|
42
|
+
* return { status: 'ok' };
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @example GraphQL
|
|
47
|
+
* ```typescript
|
|
48
|
+
* @Public()
|
|
49
|
+
* @Query(() => String)
|
|
50
|
+
* async getHealth(): Promise<string> {
|
|
51
|
+
* return 'OK';
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export const Public = () => createConditionalDecorator({
|
|
56
|
+
key: IS_PUBLIC_KEY,
|
|
57
|
+
value: true,
|
|
58
|
+
});
|
|
59
|
+
/**
|
|
60
|
+
* Decorator to mark routes/resolvers as requiring authentication
|
|
61
|
+
*
|
|
62
|
+
* This decorator sets the IS_PUBLIC_KEY metadata to false, ensuring that
|
|
63
|
+
* authentication guards will require valid credentials for the decorated endpoint.
|
|
64
|
+
*
|
|
65
|
+
* @returns Method decorator that marks the endpoint as requiring authentication
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* @Auth()
|
|
70
|
+
* @Get('profile')
|
|
71
|
+
* getProfile() {
|
|
72
|
+
* // This endpoint requires authentication
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @example GraphQL
|
|
77
|
+
* ```typescript
|
|
78
|
+
* @Auth()
|
|
79
|
+
* @Query(() => User)
|
|
80
|
+
* async getCurrentUser(@CurrentUser() user: User): Promise<User> {
|
|
81
|
+
* return user;
|
|
82
|
+
* }
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export const Auth = () => createConditionalDecorator({
|
|
86
|
+
key: IS_PUBLIC_KEY,
|
|
87
|
+
value: false,
|
|
88
|
+
});
|
|
89
|
+
/**
|
|
90
|
+
* Decorator to specify required roles for routes/resolvers
|
|
91
|
+
*
|
|
92
|
+
* This decorator sets the ROLES_KEY metadata with an array of required roles.
|
|
93
|
+
* Role guards will check that the authenticated user has at least one of the
|
|
94
|
+
* specified roles before allowing access.
|
|
95
|
+
*
|
|
96
|
+
* @param roles - Array of role names required for access
|
|
97
|
+
* @returns Method decorator that specifies role requirements
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* @Roles('admin', 'moderator')
|
|
102
|
+
* @Post('admin-action')
|
|
103
|
+
* adminAction() {
|
|
104
|
+
* // Only users with 'admin' or 'moderator' roles can access
|
|
105
|
+
* }
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* @example GraphQL
|
|
109
|
+
* ```typescript
|
|
110
|
+
* @Roles('admin')
|
|
111
|
+
* @Mutation(() => User)
|
|
112
|
+
* async updateUser(@Args('input') input: UpdateUserInput): Promise<User> {
|
|
113
|
+
* // Only admin users can update other users
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export const Roles = (...roles) => createConditionalDecorator({
|
|
118
|
+
key: ROLES_KEY,
|
|
119
|
+
value: roles,
|
|
120
|
+
});
|
|
121
|
+
/**
|
|
122
|
+
* Decorator to specify required permissions for routes/resolvers
|
|
123
|
+
*
|
|
124
|
+
* This decorator sets the PERMISSIONS_KEY metadata with an array of required permissions.
|
|
125
|
+
* Permission guards check that the authenticated user has at least one of the specified
|
|
126
|
+
* permissions (OR logic). Uses roles-as-permissions semantics — permission strings are
|
|
127
|
+
* matched against user role names.
|
|
128
|
+
*
|
|
129
|
+
* @param permissions - Array of permission names required for access
|
|
130
|
+
* @returns Method decorator that specifies permission requirements
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* @Permissions('user.create', 'user.update')
|
|
135
|
+
* @Post('users')
|
|
136
|
+
* createUser(@Body() data: CreateUserDto) {
|
|
137
|
+
* // Only users with 'user.create' OR 'user.update' role can access (roles-as-permissions)
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* @example GraphQL
|
|
142
|
+
* ```typescript
|
|
143
|
+
* @Permissions('user.delete')
|
|
144
|
+
* @Mutation(() => Boolean)
|
|
145
|
+
* async deleteUser(@Args('id') id: string): Promise<boolean> {
|
|
146
|
+
* // Only users with 'user.delete' role can delete users
|
|
147
|
+
* }
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
export const Permissions = (...permissions) => createConditionalDecorator({
|
|
151
|
+
key: PERMISSIONS_KEY,
|
|
152
|
+
value: permissions,
|
|
153
|
+
});
|
|
154
|
+
export { detectContextType, extractRequestFromContext, extractUserFromContext, extractAuthTokenFromContext } from './context-utils.js';
|
|
155
|
+
/**
|
|
156
|
+
* Parameter decorator to extract the current authenticated user
|
|
157
|
+
*
|
|
158
|
+
* This decorator injects the authenticated user object from the request context
|
|
159
|
+
* into method parameters. The user object is typically populated by authentication
|
|
160
|
+
* guards during the request processing pipeline.
|
|
161
|
+
*
|
|
162
|
+
* Supports both HTTP and GraphQL contexts with automatic detection or explicit specification.
|
|
163
|
+
*
|
|
164
|
+
* @param property - Optional property path to extract from the user object (e.g., 'id', 'profile.name')
|
|
165
|
+
* @param options - Context options for controlling extraction behavior
|
|
166
|
+
* @returns Parameter decorator that injects the current user or user property
|
|
167
|
+
*
|
|
168
|
+
* @example HTTP context (auto-detected)
|
|
169
|
+
* ```typescript
|
|
170
|
+
* @Get('profile')
|
|
171
|
+
* getProfile(@CurrentUser() user: User) {
|
|
172
|
+
* return user;
|
|
173
|
+
* }
|
|
174
|
+
* ```
|
|
175
|
+
*
|
|
176
|
+
* @example With property access
|
|
177
|
+
* ```typescript
|
|
178
|
+
* @Get('profile')
|
|
179
|
+
* getProfile(@CurrentUser('id') userId: string) {
|
|
180
|
+
* return this.userService.findById(userId);
|
|
181
|
+
* }
|
|
182
|
+
* ```
|
|
183
|
+
*
|
|
184
|
+
* @example GraphQL context (explicit)
|
|
185
|
+
* ```typescript
|
|
186
|
+
* @Query(() => User)
|
|
187
|
+
* async getCurrentUser(@CurrentUser(undefined, { contextType: 'graphql' }) user: User): Promise<User> {
|
|
188
|
+
* return user;
|
|
189
|
+
* }
|
|
190
|
+
* ```
|
|
191
|
+
*
|
|
192
|
+
* @example Auto-detect context
|
|
193
|
+
* ```typescript
|
|
194
|
+
* @UseGuards(AuthGuard)
|
|
195
|
+
* getData(@CurrentUser() user: User) {
|
|
196
|
+
* // Works in both HTTP and GraphQL contexts
|
|
197
|
+
* }
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
export function CurrentUser(property, options) {
|
|
201
|
+
return createParamDecorator((_data, ctx) => {
|
|
202
|
+
const request = ExtractRequestFromContext(ctx, options);
|
|
203
|
+
const user = request?.user;
|
|
204
|
+
if (property !== undefined && user) {
|
|
205
|
+
return user[property];
|
|
206
|
+
}
|
|
207
|
+
return user;
|
|
208
|
+
})();
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Parameter decorator to extract the authorization token from request headers
|
|
212
|
+
*
|
|
213
|
+
* This decorator injects the raw authorization token from the request headers
|
|
214
|
+
* into method parameters. Useful for custom token validation or when you need
|
|
215
|
+
* access to the raw token string.
|
|
216
|
+
*
|
|
217
|
+
* Supports both HTTP and GraphQL contexts with automatic detection or explicit specification.
|
|
218
|
+
*
|
|
219
|
+
* @param options - Context options for controlling extraction behavior
|
|
220
|
+
* @returns Parameter decorator that injects the authorization token
|
|
221
|
+
*
|
|
222
|
+
* @example HTTP context (auto-detected)
|
|
223
|
+
* ```typescript
|
|
224
|
+
* @Get('validate-token')
|
|
225
|
+
* validateToken(@AuthToken() token: string) {
|
|
226
|
+
* return this.authService.validateToken(token);
|
|
227
|
+
* }
|
|
228
|
+
* ```
|
|
229
|
+
*
|
|
230
|
+
* @example GraphQL context (explicit)
|
|
231
|
+
* ```typescript
|
|
232
|
+
* @Query(() => Boolean)
|
|
233
|
+
* async validateToken(@AuthToken({ contextType: 'graphql' }) token: string): Promise<boolean> {
|
|
234
|
+
* return this.authService.validateToken(token);
|
|
235
|
+
* }
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
export function AuthToken(options) {
|
|
239
|
+
return createParamDecorator((_data, ctx) => {
|
|
240
|
+
const request = ExtractRequestFromContext(ctx, options);
|
|
241
|
+
if (!request?.headers) {
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
const authHeader = request.headers.authorization ?? request.headers.Authorization;
|
|
245
|
+
if (typeof authHeader === 'string') {
|
|
246
|
+
return authHeader.replace(/^Bearer\s+/i, '');
|
|
247
|
+
}
|
|
248
|
+
return undefined;
|
|
249
|
+
})();
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=auth-decorators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-decorators.js","sourceRoot":"","sources":["../../src/decorators/auth-decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAoB,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAkB,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAE/E;;;;;;;;GAQG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;AAExC;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC;AAEjC;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,GAAoB,EAAE,CAAC,0BAA0B,CAAC;IACvE,GAAG,EAAE,aAAa;IAClB,KAAK,EAAE,IAAI;CACX,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,GAAoB,EAAE,CAAC,0BAA0B,CAAC;IACrE,GAAG,EAAE,aAAa;IAClB,KAAK,EAAE,KAAK;CACZ,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,GAAG,KAAe,EAAmB,EAAE,CAAC,0BAA0B,CAAC;IACxF,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,KAAK;CACZ,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAG,WAAqB,EAAmB,EAAE,CAAC,0BAA0B,CAAC;IACpG,GAAG,EAAE,eAAe;IACpB,KAAK,EAAE,WAAW;CAClB,CAAC,CAAC;AAIH,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEvI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,UAAU,WAAW,CAAC,QAAiB,EAAE,OAAwB;IACtE,OAAO,oBAAoB,CAC1B,CAAC,KAAc,EAAE,GAAqB,EAAE,EAAE;QACzC,MAAM,OAAO,GAAG,yBAAyB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;QAE3B,IAAI,QAAQ,KAAK,SAAS,IAAI,IAAI,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC,CACD,EAAE,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,SAAS,CAAC,OAAwB;IACjD,OAAO,oBAAoB,CAC1B,CAAC,KAAc,EAAE,GAAqB,EAAE,EAAE;QACzC,MAAM,OAAO,GAAG,yBAAyB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAExD,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;YACvB,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QAElF,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;YACpC,OAAO,UAAU,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC,CACD,EAAE,CAAC;AACL,CAAC"}
|