nucleus-core-ts 0.9.111 → 0.9.113
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/dist/client.js +1 -1
- package/dist/index.js +11 -10
- package/dist/src/Client/ApiCaller/system-tables.d.ts +55 -0
- package/dist/src/Client/ApiCaller/types.d.ts +142 -0
- package/dist/src/ElysiaPlugin/routes/auth/cohort/index.d.ts +30 -0
- package/dist/src/ElysiaPlugin/routes/auth/cohort/types.d.ts +22 -0
- package/dist/src/ElysiaPlugin/routes/auth/emailExempt.d.ts +9 -0
- package/dist/src/ElysiaPlugin/routes/auth/types.d.ts +1 -0
- package/dist/src/types.d.ts +26 -0
- package/package.json +1 -1
- package/schemas/config.nucleus.json +41 -0
- package/src/system.tables.json +83 -0
|
@@ -55,6 +55,14 @@ export declare const SYSTEM_TABLES: readonly [{
|
|
|
55
55
|
readonly name: "is_god";
|
|
56
56
|
readonly type: "boolean";
|
|
57
57
|
readonly default: false;
|
|
58
|
+
}, {
|
|
59
|
+
readonly name: "cohort_id";
|
|
60
|
+
readonly type: "uuid";
|
|
61
|
+
readonly references: {
|
|
62
|
+
readonly table: "user_cohorts";
|
|
63
|
+
readonly column: "id";
|
|
64
|
+
readonly onDelete: "set null";
|
|
65
|
+
};
|
|
58
66
|
}];
|
|
59
67
|
readonly indexes: readonly [{
|
|
60
68
|
readonly columns: readonly ["email"];
|
|
@@ -65,6 +73,53 @@ export declare const SYSTEM_TABLES: readonly [{
|
|
|
65
73
|
readonly columns: readonly ["last_login_at"];
|
|
66
74
|
}, {
|
|
67
75
|
readonly columns: readonly ["is_locked", "locked_until"];
|
|
76
|
+
}, {
|
|
77
|
+
readonly columns: readonly ["cohort_id"];
|
|
78
|
+
}];
|
|
79
|
+
}, {
|
|
80
|
+
readonly table_name: "user_cohorts";
|
|
81
|
+
readonly feature_set: readonly ["authentication"];
|
|
82
|
+
readonly add_base_columns: true;
|
|
83
|
+
readonly is_form_data: false;
|
|
84
|
+
readonly available_app_ids: readonly ["default_be"];
|
|
85
|
+
readonly available_schemas: readonly ["*"];
|
|
86
|
+
readonly excluded_schemas: readonly [];
|
|
87
|
+
readonly excluded_methods: readonly [];
|
|
88
|
+
readonly columns: readonly [{
|
|
89
|
+
readonly name: "name";
|
|
90
|
+
readonly type: "varchar";
|
|
91
|
+
readonly length: 255;
|
|
92
|
+
readonly notNull: true;
|
|
93
|
+
}, {
|
|
94
|
+
readonly name: "description";
|
|
95
|
+
readonly type: "text";
|
|
96
|
+
}, {
|
|
97
|
+
readonly name: "created_by";
|
|
98
|
+
readonly type: "uuid";
|
|
99
|
+
readonly references: {
|
|
100
|
+
readonly table: "users";
|
|
101
|
+
readonly column: "id";
|
|
102
|
+
readonly onDelete: "set null";
|
|
103
|
+
};
|
|
104
|
+
}, {
|
|
105
|
+
readonly name: "expires_at";
|
|
106
|
+
readonly type: "timestamptz";
|
|
107
|
+
}, {
|
|
108
|
+
readonly name: "user_count";
|
|
109
|
+
readonly type: "integer";
|
|
110
|
+
readonly notNull: true;
|
|
111
|
+
readonly default: 0;
|
|
112
|
+
}, {
|
|
113
|
+
readonly name: "metadata";
|
|
114
|
+
readonly type: "jsonb";
|
|
115
|
+
readonly default: "{}";
|
|
116
|
+
}];
|
|
117
|
+
readonly indexes: readonly [{
|
|
118
|
+
readonly columns: readonly ["name"];
|
|
119
|
+
}, {
|
|
120
|
+
readonly columns: readonly ["expires_at"];
|
|
121
|
+
}, {
|
|
122
|
+
readonly columns: readonly ["created_by"];
|
|
68
123
|
}];
|
|
69
124
|
}, {
|
|
70
125
|
readonly table_name: "profiles";
|
|
@@ -1617,6 +1617,7 @@ export type SystemPaymentPriceEntity = InferEntity<SystemTables, 'payment_prices
|
|
|
1617
1617
|
export type SystemPaymentCustomerEntity = InferEntity<SystemTables, 'payment_customers'>;
|
|
1618
1618
|
export type SystemPaymentSubscriptionEntity = InferEntity<SystemTables, 'payment_subscriptions'>;
|
|
1619
1619
|
export type SystemPaymentInvoiceEntity = InferEntity<SystemTables, 'payment_invoices'>;
|
|
1620
|
+
export type SystemUserCohortEntity = InferEntity<SystemTables, 'user_cohorts'>;
|
|
1620
1621
|
export type MeResponseData = {
|
|
1621
1622
|
user: SystemUserEntity;
|
|
1622
1623
|
profile: SystemProfileEntity | null;
|
|
@@ -3077,3 +3078,144 @@ export declare const MONITORING_ENDPOINT_CONFIGS: {
|
|
|
3077
3078
|
_error: BaseErrorResponse;
|
|
3078
3079
|
};
|
|
3079
3080
|
};
|
|
3081
|
+
export type CohortPayload = {
|
|
3082
|
+
name: string;
|
|
3083
|
+
description?: string;
|
|
3084
|
+
expiresAt?: string;
|
|
3085
|
+
metadata?: Record<string, unknown>;
|
|
3086
|
+
};
|
|
3087
|
+
export type CohortUpdatePayload = {
|
|
3088
|
+
id: string;
|
|
3089
|
+
name?: string;
|
|
3090
|
+
description?: string;
|
|
3091
|
+
expiresAt?: string | null;
|
|
3092
|
+
isActive?: boolean;
|
|
3093
|
+
metadata?: Record<string, unknown>;
|
|
3094
|
+
};
|
|
3095
|
+
export type BulkCreateUsersPayload = {
|
|
3096
|
+
users?: Array<{
|
|
3097
|
+
email: string;
|
|
3098
|
+
password: string;
|
|
3099
|
+
profile?: {
|
|
3100
|
+
firstName?: string;
|
|
3101
|
+
lastName?: string;
|
|
3102
|
+
};
|
|
3103
|
+
}>;
|
|
3104
|
+
emailPrefix?: string;
|
|
3105
|
+
emailDomain?: string;
|
|
3106
|
+
sharedPassword?: string;
|
|
3107
|
+
count?: number;
|
|
3108
|
+
roleIds?: string[];
|
|
3109
|
+
};
|
|
3110
|
+
export type BulkCreateUsersResponse = {
|
|
3111
|
+
created: number;
|
|
3112
|
+
skipped: number;
|
|
3113
|
+
skippedEmails: string[];
|
|
3114
|
+
users: Array<{
|
|
3115
|
+
id: string;
|
|
3116
|
+
email: string;
|
|
3117
|
+
}>;
|
|
3118
|
+
};
|
|
3119
|
+
export type CohortBulkOpsResponse = {
|
|
3120
|
+
affected: number;
|
|
3121
|
+
};
|
|
3122
|
+
export declare const COHORT_ENDPOINT_CONFIGS: {
|
|
3123
|
+
listCohorts: {
|
|
3124
|
+
key: "ADMIN_LIST_COHORTS";
|
|
3125
|
+
method: "GET";
|
|
3126
|
+
path: string;
|
|
3127
|
+
_payload: StandardQueryParams;
|
|
3128
|
+
_success: ListResponse<SystemUserCohortEntity>;
|
|
3129
|
+
_error: BaseErrorResponse;
|
|
3130
|
+
};
|
|
3131
|
+
getCohort: {
|
|
3132
|
+
key: "ADMIN_GET_COHORT";
|
|
3133
|
+
method: "GET";
|
|
3134
|
+
path: string;
|
|
3135
|
+
_payload: {
|
|
3136
|
+
id: string;
|
|
3137
|
+
};
|
|
3138
|
+
_success: SingleResponse<SystemUserCohortEntity & {
|
|
3139
|
+
users: SystemUserEntity[];
|
|
3140
|
+
}>;
|
|
3141
|
+
_error: BaseErrorResponse;
|
|
3142
|
+
};
|
|
3143
|
+
createCohort: {
|
|
3144
|
+
key: "ADMIN_CREATE_COHORT";
|
|
3145
|
+
method: "POST";
|
|
3146
|
+
path: string;
|
|
3147
|
+
_payload: CohortPayload;
|
|
3148
|
+
_success: MutationResponse<SystemUserCohortEntity>;
|
|
3149
|
+
_error: BaseErrorResponse;
|
|
3150
|
+
};
|
|
3151
|
+
updateCohort: {
|
|
3152
|
+
key: "ADMIN_UPDATE_COHORT";
|
|
3153
|
+
method: "PATCH";
|
|
3154
|
+
path: string;
|
|
3155
|
+
_payload: CohortUpdatePayload;
|
|
3156
|
+
_success: MutationResponse<SystemUserCohortEntity>;
|
|
3157
|
+
_error: BaseErrorResponse;
|
|
3158
|
+
};
|
|
3159
|
+
deleteCohort: {
|
|
3160
|
+
key: "ADMIN_DELETE_COHORT";
|
|
3161
|
+
method: "DELETE";
|
|
3162
|
+
path: string;
|
|
3163
|
+
_payload: {
|
|
3164
|
+
id: string;
|
|
3165
|
+
};
|
|
3166
|
+
_success: DeleteResponse;
|
|
3167
|
+
_error: BaseErrorResponse;
|
|
3168
|
+
};
|
|
3169
|
+
bulkCreateUsers: {
|
|
3170
|
+
key: "ADMIN_COHORT_BULK_CREATE";
|
|
3171
|
+
method: "POST";
|
|
3172
|
+
path: string;
|
|
3173
|
+
_payload: BulkCreateUsersPayload & {
|
|
3174
|
+
id: string;
|
|
3175
|
+
};
|
|
3176
|
+
_success: MutationResponse<BulkCreateUsersResponse>;
|
|
3177
|
+
_error: BaseErrorResponse;
|
|
3178
|
+
};
|
|
3179
|
+
deactivateUsers: {
|
|
3180
|
+
key: "ADMIN_COHORT_DEACTIVATE";
|
|
3181
|
+
method: "POST";
|
|
3182
|
+
path: string;
|
|
3183
|
+
_payload: {
|
|
3184
|
+
id: string;
|
|
3185
|
+
};
|
|
3186
|
+
_success: MutationResponse<CohortBulkOpsResponse>;
|
|
3187
|
+
_error: BaseErrorResponse;
|
|
3188
|
+
};
|
|
3189
|
+
activateUsers: {
|
|
3190
|
+
key: "ADMIN_COHORT_ACTIVATE";
|
|
3191
|
+
method: "POST";
|
|
3192
|
+
path: string;
|
|
3193
|
+
_payload: {
|
|
3194
|
+
id: string;
|
|
3195
|
+
};
|
|
3196
|
+
_success: MutationResponse<CohortBulkOpsResponse>;
|
|
3197
|
+
_error: BaseErrorResponse;
|
|
3198
|
+
};
|
|
3199
|
+
deleteUsers: {
|
|
3200
|
+
key: "ADMIN_COHORT_DELETE_USERS";
|
|
3201
|
+
method: "POST";
|
|
3202
|
+
path: string;
|
|
3203
|
+
_payload: {
|
|
3204
|
+
id: string;
|
|
3205
|
+
};
|
|
3206
|
+
_success: MutationResponse<{
|
|
3207
|
+
deleted: number;
|
|
3208
|
+
}>;
|
|
3209
|
+
_error: BaseErrorResponse;
|
|
3210
|
+
};
|
|
3211
|
+
exportUsers: {
|
|
3212
|
+
key: "ADMIN_COHORT_EXPORT";
|
|
3213
|
+
method: "GET";
|
|
3214
|
+
path: string;
|
|
3215
|
+
_payload: {
|
|
3216
|
+
id: string;
|
|
3217
|
+
};
|
|
3218
|
+
_success: string;
|
|
3219
|
+
_error: BaseErrorResponse;
|
|
3220
|
+
};
|
|
3221
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Elysia } from 'elysia';
|
|
2
|
+
import type { CohortRouteConfig } from './types';
|
|
3
|
+
export declare function createCohortRoutes(config: CohortRouteConfig): Elysia<"", {
|
|
4
|
+
decorator: {};
|
|
5
|
+
store: {};
|
|
6
|
+
derive: {};
|
|
7
|
+
resolve: {};
|
|
8
|
+
}, {
|
|
9
|
+
typebox: {};
|
|
10
|
+
error: {};
|
|
11
|
+
}, {
|
|
12
|
+
schema: {};
|
|
13
|
+
standaloneSchema: {};
|
|
14
|
+
macro: {};
|
|
15
|
+
macroFn: {};
|
|
16
|
+
parser: {};
|
|
17
|
+
response: {};
|
|
18
|
+
}, {}, {
|
|
19
|
+
derive: {};
|
|
20
|
+
resolve: {};
|
|
21
|
+
schema: {};
|
|
22
|
+
standaloneSchema: {};
|
|
23
|
+
response: {};
|
|
24
|
+
}, {
|
|
25
|
+
derive: {};
|
|
26
|
+
resolve: {};
|
|
27
|
+
schema: {};
|
|
28
|
+
standaloneSchema: {};
|
|
29
|
+
response: {};
|
|
30
|
+
}>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
|
2
|
+
import type { Logger } from 'src/Services';
|
|
3
|
+
export type CohortRouteConfig = {
|
|
4
|
+
db: NodePgDatabase | null;
|
|
5
|
+
logger: Logger;
|
|
6
|
+
cohortsTable: ReturnType<typeof import('drizzle-orm/pg-core').pgTable> | null;
|
|
7
|
+
usersTable: ReturnType<typeof import('drizzle-orm/pg-core').pgTable> | null;
|
|
8
|
+
rolesTable: ReturnType<typeof import('drizzle-orm/pg-core').pgTable> | null;
|
|
9
|
+
userRolesTable: ReturnType<typeof import('drizzle-orm/pg-core').pgTable> | null;
|
|
10
|
+
profilesTable: ReturnType<typeof import('drizzle-orm/pg-core').pgTable> | null;
|
|
11
|
+
basePath: string;
|
|
12
|
+
passwordPolicy?: {
|
|
13
|
+
minLength?: number;
|
|
14
|
+
maxLength?: number;
|
|
15
|
+
requireUppercase?: boolean;
|
|
16
|
+
requireLowercase?: boolean;
|
|
17
|
+
requireNumber?: boolean;
|
|
18
|
+
requireSpecialChar?: boolean;
|
|
19
|
+
};
|
|
20
|
+
defaultRole?: string;
|
|
21
|
+
emailExemptDomains?: string[];
|
|
22
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if an email address belongs to a domain exempted from
|
|
3
|
+
* email-based operations (notifications, verification, password reset emails,
|
|
4
|
+
* suspicious login alerts, device approval flows).
|
|
5
|
+
*
|
|
6
|
+
* Exempt users still authenticate normally and are fully audited — only
|
|
7
|
+
* outbound email operations are skipped.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isEmailExempt(email: string, exemptDomains: string[] | undefined): boolean;
|
package/dist/src/types.d.ts
CHANGED
|
@@ -165,6 +165,32 @@ export interface NucleusConfigOptions {
|
|
|
165
165
|
* Use leading dot to cover all subdomains: ".vorion.ai"
|
|
166
166
|
*/
|
|
167
167
|
cookieDomain?: string;
|
|
168
|
+
/**
|
|
169
|
+
* Email domains exempt from all email-based operations:
|
|
170
|
+
* login notifications, email verification, password reset emails,
|
|
171
|
+
* suspicious login alerts, and device approval flows.
|
|
172
|
+
* Users with matching domains still authenticate normally and are fully audited.
|
|
173
|
+
* Example: ["vorionai.com", "training.local"]
|
|
174
|
+
*/
|
|
175
|
+
emailExemptDomains?: string[];
|
|
176
|
+
/**
|
|
177
|
+
* Admin user creation configuration.
|
|
178
|
+
*/
|
|
179
|
+
adminCreateUser?: {
|
|
180
|
+
enabled?: boolean;
|
|
181
|
+
route?: string;
|
|
182
|
+
allowRoles?: string[];
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* User cohort (batch) management configuration.
|
|
186
|
+
* Cohorts group users for bulk lifecycle management (training sessions, demos, etc.)
|
|
187
|
+
*/
|
|
188
|
+
cohorts?: {
|
|
189
|
+
enabled?: boolean;
|
|
190
|
+
basePath?: string;
|
|
191
|
+
/** Auto-lock cohort users when cohort expires_at is reached. Checked on startup + hourly. */
|
|
192
|
+
autoExpireLock?: boolean;
|
|
193
|
+
};
|
|
168
194
|
passwordPolicy?: {
|
|
169
195
|
minLength?: number;
|
|
170
196
|
maxLength?: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nucleus-core-ts",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.113",
|
|
4
4
|
"description": "Production-ready, enterprise-grade TypeScript framework for building multi-tenant APIs",
|
|
5
5
|
"author": "Hidayet Can Özcan <hidayetcan@gmail.com>",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -136,6 +136,47 @@
|
|
|
136
136
|
"type": "string",
|
|
137
137
|
"description": "Cookie domain for cross-subdomain auth sharing. Set to env var name (e.g. \"COOKIE_DOMAIN\") or literal value (e.g. \".vorion.ai\"). Use leading dot to cover all subdomains: \".vorion.ai\""
|
|
138
138
|
},
|
|
139
|
+
"emailExemptDomains": {
|
|
140
|
+
"type": "array",
|
|
141
|
+
"items": {
|
|
142
|
+
"type": "string"
|
|
143
|
+
},
|
|
144
|
+
"description": "Email domains exempt from all email-based operations: login notifications, email verification, password reset emails, suspicious login alerts, and device approval flows. Users with matching domains still authenticate normally and are fully audited. Example: [\"vorionai.com\", \"training.local\"]"
|
|
145
|
+
},
|
|
146
|
+
"adminCreateUser": {
|
|
147
|
+
"type": "object",
|
|
148
|
+
"properties": {
|
|
149
|
+
"enabled": {
|
|
150
|
+
"type": "boolean"
|
|
151
|
+
},
|
|
152
|
+
"route": {
|
|
153
|
+
"type": "string"
|
|
154
|
+
},
|
|
155
|
+
"allowRoles": {
|
|
156
|
+
"type": "array",
|
|
157
|
+
"items": {
|
|
158
|
+
"type": "string"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
"description": "Admin user creation configuration."
|
|
163
|
+
},
|
|
164
|
+
"cohorts": {
|
|
165
|
+
"type": "object",
|
|
166
|
+
"properties": {
|
|
167
|
+
"enabled": {
|
|
168
|
+
"type": "boolean"
|
|
169
|
+
},
|
|
170
|
+
"basePath": {
|
|
171
|
+
"type": "string"
|
|
172
|
+
},
|
|
173
|
+
"autoExpireLock": {
|
|
174
|
+
"type": "boolean",
|
|
175
|
+
"description": "Auto-lock cohort users when cohort expires_at is reached. Checked on startup + hourly."
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
"description": "User cohort (batch) management configuration. Cohorts group users for bulk lifecycle management (training sessions, demos, etc.)"
|
|
179
|
+
},
|
|
139
180
|
"passwordPolicy": {
|
|
140
181
|
"type": "object",
|
|
141
182
|
"properties": {
|
package/src/system.tables.json
CHANGED
|
@@ -77,6 +77,15 @@
|
|
|
77
77
|
"name": "is_god",
|
|
78
78
|
"type": "boolean",
|
|
79
79
|
"default": false
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "cohort_id",
|
|
83
|
+
"type": "uuid",
|
|
84
|
+
"references": {
|
|
85
|
+
"table": "user_cohorts",
|
|
86
|
+
"column": "id",
|
|
87
|
+
"onDelete": "set null"
|
|
88
|
+
}
|
|
80
89
|
}
|
|
81
90
|
],
|
|
82
91
|
"indexes": [
|
|
@@ -102,6 +111,80 @@
|
|
|
102
111
|
"is_locked",
|
|
103
112
|
"locked_until"
|
|
104
113
|
]
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"columns": [
|
|
117
|
+
"cohort_id"
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"table_name": "user_cohorts",
|
|
124
|
+
"feature_set": [
|
|
125
|
+
"authentication"
|
|
126
|
+
],
|
|
127
|
+
"add_base_columns": true,
|
|
128
|
+
"is_form_data": false,
|
|
129
|
+
"available_app_ids": [
|
|
130
|
+
"default_be"
|
|
131
|
+
],
|
|
132
|
+
"available_schemas": [
|
|
133
|
+
"*"
|
|
134
|
+
],
|
|
135
|
+
"excluded_schemas": [],
|
|
136
|
+
"excluded_methods": [],
|
|
137
|
+
"columns": [
|
|
138
|
+
{
|
|
139
|
+
"name": "name",
|
|
140
|
+
"type": "varchar",
|
|
141
|
+
"length": 255,
|
|
142
|
+
"notNull": true
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"name": "description",
|
|
146
|
+
"type": "text"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"name": "created_by",
|
|
150
|
+
"type": "uuid",
|
|
151
|
+
"references": {
|
|
152
|
+
"table": "users",
|
|
153
|
+
"column": "id",
|
|
154
|
+
"onDelete": "set null"
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"name": "expires_at",
|
|
159
|
+
"type": "timestamptz"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"name": "user_count",
|
|
163
|
+
"type": "integer",
|
|
164
|
+
"notNull": true,
|
|
165
|
+
"default": 0
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"name": "metadata",
|
|
169
|
+
"type": "jsonb",
|
|
170
|
+
"default": "{}"
|
|
171
|
+
}
|
|
172
|
+
],
|
|
173
|
+
"indexes": [
|
|
174
|
+
{
|
|
175
|
+
"columns": [
|
|
176
|
+
"name"
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"columns": [
|
|
181
|
+
"expires_at"
|
|
182
|
+
]
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"columns": [
|
|
186
|
+
"created_by"
|
|
187
|
+
]
|
|
105
188
|
}
|
|
106
189
|
]
|
|
107
190
|
},
|