@nauth-toolkit/core 0.1.0 → 0.1.5
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 +90 -0
- package/README.md +9 -0
- package/package.json +8 -3
- package/jest.config.js +0 -15
- package/jest.setup.ts +0 -6
- package/src/adapters/database-columns.ts +0 -165
- package/src/adapters/express.adapter.ts +0 -385
- package/src/adapters/fastify.adapter.ts +0 -416
- package/src/adapters/index.ts +0 -16
- package/src/adapters/storage.factory.ts +0 -143
- package/src/bootstrap.ts +0 -374
- package/src/dto/auth-challenge.dto.ts +0 -231
- package/src/dto/auth-response.dto.ts +0 -253
- package/src/dto/challenge-response.dto.ts +0 -234
- package/src/dto/change-password-request.dto.ts +0 -50
- package/src/dto/change-password-response.dto.ts +0 -29
- package/src/dto/change-password.dto.ts +0 -57
- package/src/dto/error-response.dto.ts +0 -136
- package/src/dto/get-available-methods.dto.ts +0 -55
- package/src/dto/get-challenge-data-response.dto.ts +0 -28
- package/src/dto/get-challenge-data.dto.ts +0 -69
- package/src/dto/get-client-info.dto.ts +0 -104
- package/src/dto/get-device-token-response.dto.ts +0 -25
- package/src/dto/get-events-by-type.dto.ts +0 -76
- package/src/dto/get-ip-address-response.dto.ts +0 -24
- package/src/dto/get-mfa-status.dto.ts +0 -94
- package/src/dto/get-risk-assessment-history.dto.ts +0 -39
- package/src/dto/get-session-id-response.dto.ts +0 -25
- package/src/dto/get-setup-data-response.dto.ts +0 -31
- package/src/dto/get-setup-data.dto.ts +0 -75
- package/src/dto/get-suspicious-activity.dto.ts +0 -42
- package/src/dto/get-user-agent-response.dto.ts +0 -23
- package/src/dto/get-user-auth-history.dto.ts +0 -95
- package/src/dto/get-user-by-email.dto.ts +0 -61
- package/src/dto/get-user-by-id.dto.ts +0 -46
- package/src/dto/get-user-devices.dto.ts +0 -53
- package/src/dto/get-user-response.dto.ts +0 -17
- package/src/dto/has-provider.dto.ts +0 -56
- package/src/dto/index.ts +0 -57
- package/src/dto/is-trusted-device-response.dto.ts +0 -34
- package/src/dto/list-providers-response.dto.ts +0 -23
- package/src/dto/login.dto.ts +0 -95
- package/src/dto/logout-all-response.dto.ts +0 -24
- package/src/dto/logout-all.dto.ts +0 -65
- package/src/dto/logout-response.dto.ts +0 -25
- package/src/dto/logout.dto.ts +0 -64
- package/src/dto/refresh-token.dto.ts +0 -36
- package/src/dto/remove-devices.dto.ts +0 -85
- package/src/dto/resend-code-response.dto.ts +0 -32
- package/src/dto/resend-code.dto.ts +0 -51
- package/src/dto/reset-password.dto.ts +0 -115
- package/src/dto/respond-challenge.dto.ts +0 -272
- package/src/dto/set-mfa-exemption.dto.ts +0 -112
- package/src/dto/set-must-change-password-response.dto.ts +0 -27
- package/src/dto/set-must-change-password.dto.ts +0 -46
- package/src/dto/set-preferred-method.dto.ts +0 -80
- package/src/dto/setup-mfa.dto.ts +0 -98
- package/src/dto/signup.dto.ts +0 -174
- package/src/dto/social-auth.dto.ts +0 -422
- package/src/dto/trust-device-response.dto.ts +0 -30
- package/src/dto/trust-device.dto.ts +0 -9
- package/src/dto/update-user-attributes-request.dto.ts +0 -51
- package/src/dto/user-response.dto.ts +0 -138
- package/src/dto/user-update.dto.ts +0 -222
- package/src/dto/verify-email.dto.ts +0 -313
- package/src/dto/verify-mfa-code.dto.ts +0 -103
- package/src/dto/verify-phone-by-sub.dto.ts +0 -78
- package/src/dto/verify-phone.dto.ts +0 -245
- package/src/entities/auth-audit.entity.ts +0 -232
- package/src/entities/challenge-session.entity.ts +0 -116
- package/src/entities/index.ts +0 -29
- package/src/entities/login-attempt.entity.ts +0 -64
- package/src/entities/mfa-device.entity.ts +0 -151
- package/src/entities/rate-limit.entity.ts +0 -44
- package/src/entities/session.entity.ts +0 -180
- package/src/entities/social-account.entity.ts +0 -96
- package/src/entities/storage-lock.entity.ts +0 -39
- package/src/entities/trusted-device.entity.ts +0 -112
- package/src/entities/user.entity.ts +0 -243
- package/src/entities/verification-token.entity.ts +0 -141
- package/src/enums/auth-audit-event-type.enum.ts +0 -360
- package/src/enums/error-codes.enum.ts +0 -420
- package/src/enums/mfa-method.enum.ts +0 -97
- package/src/enums/risk-factor.enum.ts +0 -111
- package/src/exceptions/nauth.exception.ts +0 -231
- package/src/handlers/auth.handler.ts +0 -260
- package/src/handlers/client-info.handler.ts +0 -101
- package/src/handlers/csrf.handler.ts +0 -156
- package/src/handlers/token-delivery.handler.ts +0 -118
- package/src/index.ts +0 -118
- package/src/interfaces/client-info.interface.ts +0 -85
- package/src/interfaces/config.interface.ts +0 -2135
- package/src/interfaces/entities.interface.ts +0 -226
- package/src/interfaces/index.ts +0 -15
- package/src/interfaces/logger.interface.ts +0 -283
- package/src/interfaces/mfa-provider.interface.ts +0 -154
- package/src/interfaces/oauth.interface.ts +0 -148
- package/src/interfaces/provider.interface.ts +0 -47
- package/src/interfaces/social-auth-provider.interface.ts +0 -131
- package/src/interfaces/storage-adapter.interface.ts +0 -82
- package/src/interfaces/template.interface.ts +0 -510
- package/src/interfaces/token-verifier.interface.ts +0 -110
- package/src/internal.ts +0 -178
- package/src/platform/interfaces.ts +0 -299
- package/src/schemas/auth-config.schema.ts +0 -646
- package/src/services/adaptive-mfa-decision.service.spec.ts +0 -1058
- package/src/services/adaptive-mfa-decision.service.ts +0 -457
- package/src/services/auth-audit.service.spec.ts +0 -675
- package/src/services/auth-audit.service.ts +0 -558
- package/src/services/auth-challenge-helper.service.spec.ts +0 -3227
- package/src/services/auth-challenge-helper.service.ts +0 -825
- package/src/services/auth-flow-context-builder.service.ts +0 -520
- package/src/services/auth-flow-rules.ts +0 -202
- package/src/services/auth-flow-state-definitions.ts +0 -190
- package/src/services/auth-flow-state-machine.service.ts +0 -207
- package/src/services/auth-flow-state-machine.types.ts +0 -316
- package/src/services/auth.service.spec.ts +0 -4195
- package/src/services/auth.service.ts +0 -3727
- package/src/services/challenge.service.spec.ts +0 -1363
- package/src/services/challenge.service.ts +0 -696
- package/src/services/client-info.service.spec.ts +0 -572
- package/src/services/client-info.service.ts +0 -374
- package/src/services/csrf.service.ts +0 -54
- package/src/services/email-verification.service.spec.ts +0 -1229
- package/src/services/email-verification.service.ts +0 -578
- package/src/services/geo-location.service.spec.ts +0 -603
- package/src/services/geo-location.service.ts +0 -599
- package/src/services/index.ts +0 -13
- package/src/services/jwt.service.spec.ts +0 -882
- package/src/services/jwt.service.ts +0 -621
- package/src/services/mfa-base.service.spec.ts +0 -246
- package/src/services/mfa-base.service.ts +0 -611
- package/src/services/mfa.service.spec.ts +0 -693
- package/src/services/mfa.service.ts +0 -960
- package/src/services/password.service.spec.ts +0 -166
- package/src/services/password.service.ts +0 -309
- package/src/services/phone-verification.service.spec.ts +0 -1120
- package/src/services/phone-verification.service.ts +0 -751
- package/src/services/risk-detection.service.spec.ts +0 -1292
- package/src/services/risk-detection.service.ts +0 -1012
- package/src/services/risk-scoring.service.spec.ts +0 -204
- package/src/services/risk-scoring.service.ts +0 -131
- package/src/services/session.service.spec.ts +0 -1293
- package/src/services/session.service.ts +0 -803
- package/src/services/social-account.service.spec.ts +0 -725
- package/src/services/social-auth-base.service.spec.ts +0 -418
- package/src/services/social-auth-base.service.ts +0 -581
- package/src/services/social-auth.service.spec.ts +0 -238
- package/src/services/social-auth.service.ts +0 -436
- package/src/services/social-provider-registry.service.spec.ts +0 -238
- package/src/services/social-provider-registry.service.ts +0 -122
- package/src/services/trusted-device.service.spec.ts +0 -505
- package/src/services/trusted-device.service.ts +0 -339
- package/src/storage/account-lockout-storage.service.spec.ts +0 -310
- package/src/storage/account-lockout-storage.service.ts +0 -89
- package/src/storage/index.ts +0 -3
- package/src/storage/memory-storage.adapter.ts +0 -443
- package/src/storage/rate-limit-storage.service.spec.ts +0 -247
- package/src/storage/rate-limit-storage.service.ts +0 -38
- package/src/templates/html-template.engine.spec.ts +0 -161
- package/src/templates/html-template.engine.ts +0 -688
- package/src/templates/index.ts +0 -7
- package/src/utils/common-passwords.spec.ts +0 -230
- package/src/utils/common-passwords.ts +0 -170
- package/src/utils/context-storage.ts +0 -188
- package/src/utils/cookie-names.util.ts +0 -67
- package/src/utils/cookies.util.ts +0 -94
- package/src/utils/index.ts +0 -12
- package/src/utils/ip-extractor.spec.ts +0 -330
- package/src/utils/ip-extractor.ts +0 -220
- package/src/utils/nauth-logger.spec.ts +0 -388
- package/src/utils/nauth-logger.ts +0 -215
- package/src/utils/pii-redactor.spec.ts +0 -130
- package/src/utils/pii-redactor.ts +0 -288
- package/src/utils/setup/get-repositories.ts +0 -140
- package/src/utils/setup/init-services.ts +0 -422
- package/src/utils/setup/init-social.ts +0 -189
- package/src/utils/setup/init-storage.ts +0 -94
- package/src/utils/setup/register-mfa.ts +0 -165
- package/src/utils/setup/run-nauth-migrations.ts +0 -61
- package/src/utils/token-delivery-policy.ts +0 -38
- package/src/validators/template.validator.ts +0 -219
- package/tsconfig.json +0 -37
- package/tsconfig.lint.json +0 -6
package/LICENSE
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
NAUTH TOOLKIT EARLY ACCESS LICENSE
|
|
2
|
+
Version 1.0 (December 2025)
|
|
3
|
+
|
|
4
|
+
================================================================================
|
|
5
|
+
FUTURE OPEN SOURCE NOTICE
|
|
6
|
+
================================================================================
|
|
7
|
+
NAuth Toolkit will transition to an open-source license (MIT or Apache 2.0) for
|
|
8
|
+
core authentication features once the project reaches production readiness.
|
|
9
|
+
|
|
10
|
+
This Early Access License is temporary and designed to:
|
|
11
|
+
• Allow developers to build with nauth-toolkit during preview/beta
|
|
12
|
+
• Provide clear expectations during the pre-release phase
|
|
13
|
+
• Enable feedback and real-world testing before GA
|
|
14
|
+
|
|
15
|
+
We're committed to keeping core auth free and open source. Premium features
|
|
16
|
+
(enterprise SSO, advanced compliance, hosted options) will be offered separately
|
|
17
|
+
under fair commercial terms.
|
|
18
|
+
|
|
19
|
+
================================================================================
|
|
20
|
+
EARLY ACCESS LICENSE TERMS
|
|
21
|
+
================================================================================
|
|
22
|
+
|
|
23
|
+
1. Grant of Use
|
|
24
|
+
You are granted a free, non-exclusive, non-transferable license to:
|
|
25
|
+
- Install and use nauth-toolkit packages in development, testing, staging,
|
|
26
|
+
and production environments
|
|
27
|
+
- Modify the code for your own internal use
|
|
28
|
+
- Deploy applications using nauth-toolkit to serve your users
|
|
29
|
+
|
|
30
|
+
You may NOT:
|
|
31
|
+
- Redistribute NAuth Toolkit as a standalone product or service
|
|
32
|
+
- Sell, sublicense, or offer NAuth Toolkit as part of a competing auth
|
|
33
|
+
platform or toolkit
|
|
34
|
+
- Remove or alter copyright notices
|
|
35
|
+
|
|
36
|
+
2. No Fees During Early Access
|
|
37
|
+
There are no license fees, subscription costs, or usage charges during the
|
|
38
|
+
Early Access period. You may use nauth-toolkit freely for commercial and
|
|
39
|
+
non-commercial purposes within the terms of this license.
|
|
40
|
+
|
|
41
|
+
3. Production Use
|
|
42
|
+
Production use is permitted but comes with standard early-access caveats:
|
|
43
|
+
- Features and APIs may change between preview releases
|
|
44
|
+
- Support is community-based (GitHub issues/discussions)
|
|
45
|
+
- No SLA or guaranteed uptime (you run it on your infrastructure)
|
|
46
|
+
|
|
47
|
+
We recommend thorough testing and having rollback plans for critical systems.
|
|
48
|
+
|
|
49
|
+
4. Future Transition
|
|
50
|
+
When nauth-toolkit releases v1.0 GA:
|
|
51
|
+
- Core packages will adopt an open-source license (MIT or Apache 2.0)
|
|
52
|
+
- Your existing deployments will continue to work
|
|
53
|
+
- Premium features (if any) will be clearly documented with separate licensing
|
|
54
|
+
- No forced upgrades or surprise fees
|
|
55
|
+
|
|
56
|
+
5. Ownership
|
|
57
|
+
NAuth Toolkit is developed and maintained by Noorix Digital Solutions.
|
|
58
|
+
You retain full ownership of your applications and data.
|
|
59
|
+
|
|
60
|
+
6. Data and Privacy
|
|
61
|
+
NAuth Toolkit runs in YOUR infrastructure and database. You control all data.
|
|
62
|
+
You are responsible for compliance with applicable data protection laws.
|
|
63
|
+
|
|
64
|
+
7. Disclaimer of Warranty
|
|
65
|
+
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
66
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
67
|
+
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
|
68
|
+
|
|
69
|
+
8. Limitation of Liability
|
|
70
|
+
IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
|
|
71
|
+
SPECIAL, CONSEQUENTIAL, OR EXEMPLARY DAMAGES, INCLUDING BUT NOT LIMITED TO LOSS
|
|
72
|
+
OF PROFITS, REVENUE, DATA, OR USE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
73
|
+
DAMAGES.
|
|
74
|
+
|
|
75
|
+
9. Termination
|
|
76
|
+
This license remains in effect until:
|
|
77
|
+
- You stop using nauth-toolkit, or
|
|
78
|
+
- The project transitions to open source (at which point the new license applies)
|
|
79
|
+
|
|
80
|
+
If you breach these terms, your license terminates and you must stop using the
|
|
81
|
+
software.
|
|
82
|
+
|
|
83
|
+
10. Contact and Support
|
|
84
|
+
- Documentation: https://nauth.dev
|
|
85
|
+
- Issues/Discussions: GitHub (when public repository launches)
|
|
86
|
+
- Commercial inquiries: Contact admin@noorix.com
|
|
87
|
+
|
|
88
|
+
================================================================================
|
|
89
|
+
Thank you for being an early adopter. Your feedback shapes the future of NAuth.
|
|
90
|
+
================================================================================
|
package/README.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# @nauth-toolkit/core
|
|
2
|
+
|
|
3
|
+
Core authentication toolkit for Node JS
|
|
4
|
+
|
|
5
|
+
## Preview Release Notice
|
|
6
|
+
|
|
7
|
+
**This is a preview release for internal testing. Do not use in production yet.**
|
|
8
|
+
|
|
9
|
+
This package is part of nauth-toolkit and is currently in early access/preview. Features and APIs may change between releases. For production use, please wait for the stable v1.0 release.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nauth-toolkit/core",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Core authentication toolkit for
|
|
3
|
+
"version": "0.1.5",
|
|
4
|
+
"description": "Core authentication toolkit for Node JS",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -63,11 +63,16 @@
|
|
|
63
63
|
"access": "public",
|
|
64
64
|
"tag": "preview"
|
|
65
65
|
},
|
|
66
|
-
"license": "
|
|
66
|
+
"license": "UNLICENSED",
|
|
67
67
|
"keywords": [
|
|
68
68
|
"nestjs",
|
|
69
69
|
"authentication",
|
|
70
70
|
"jwt",
|
|
71
71
|
"typeorm"
|
|
72
|
+
],
|
|
73
|
+
"files": [
|
|
74
|
+
"dist",
|
|
75
|
+
"LICENSE",
|
|
76
|
+
"README.md"
|
|
72
77
|
]
|
|
73
78
|
}
|
package/jest.config.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
moduleFileExtensions: ['js', 'json', 'ts'],
|
|
3
|
-
rootDir: 'src',
|
|
4
|
-
testRegex: '.*\\.spec\\.ts$',
|
|
5
|
-
transform: {
|
|
6
|
-
'^.+\\.(t|j)s$': 'ts-jest',
|
|
7
|
-
},
|
|
8
|
-
collectCoverageFrom: ['**/*.(t|j)s'],
|
|
9
|
-
coverageDirectory: '../coverage',
|
|
10
|
-
testEnvironment: 'node',
|
|
11
|
-
// Transform ESM modules like jose
|
|
12
|
-
transformIgnorePatterns: ['node_modules/(?!(jose)/)'],
|
|
13
|
-
// Setup reflect-metadata for TypeORM
|
|
14
|
-
setupFilesAfterEnv: ['<rootDir>/../jest.setup.ts'],
|
|
15
|
-
};
|
package/jest.setup.ts
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import { Column, ColumnOptions } from 'typeorm';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Database-Agnostic Column Decorators
|
|
5
|
-
*
|
|
6
|
-
* Provides column decorators that automatically adapt to different database types.
|
|
7
|
-
* Uses the database adapter to determine appropriate column types.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* @Entity()
|
|
12
|
-
* export class User {
|
|
13
|
-
* @UuidColumn()
|
|
14
|
-
* id!: string;
|
|
15
|
-
*
|
|
16
|
-
* @JsonColumn()
|
|
17
|
-
* metadata?: Record<string, any>;
|
|
18
|
-
*
|
|
19
|
-
* @ArrayColumn()
|
|
20
|
-
* tags?: string[];
|
|
21
|
-
* }
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Create UUID column with database-appropriate type
|
|
27
|
-
*
|
|
28
|
-
* @param options - Additional column options
|
|
29
|
-
* @returns Column decorator
|
|
30
|
-
*/
|
|
31
|
-
export function UuidColumn(options?: Partial<ColumnOptions>) {
|
|
32
|
-
return function (target: Record<string, unknown>, propertyKey: string) {
|
|
33
|
-
// This would be replaced with actual adapter-based logic
|
|
34
|
-
// For now, use PostgreSQL default
|
|
35
|
-
const columnOptions: ColumnOptions = {
|
|
36
|
-
type: 'uuid',
|
|
37
|
-
...options,
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
// In a real implementation, this would use the injected adapter
|
|
41
|
-
// to determine the correct column type
|
|
42
|
-
return Column(columnOptions)(target, propertyKey);
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Create JSON column with database-appropriate type
|
|
48
|
-
*
|
|
49
|
-
* @param options - Additional column options
|
|
50
|
-
* @returns Column decorator
|
|
51
|
-
*/
|
|
52
|
-
export function JsonColumn(options?: Partial<ColumnOptions>) {
|
|
53
|
-
return function (target: Record<string, unknown>, propertyKey: string) {
|
|
54
|
-
const columnOptions: ColumnOptions = {
|
|
55
|
-
type: 'jsonb', // PostgreSQL default
|
|
56
|
-
...options,
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
return Column(columnOptions)(target, propertyKey);
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Create array column with database-appropriate type
|
|
65
|
-
*
|
|
66
|
-
* @param options - Additional column options
|
|
67
|
-
* @returns Column decorator
|
|
68
|
-
*/
|
|
69
|
-
export function ArrayColumn(options?: Partial<ColumnOptions>) {
|
|
70
|
-
return function (target: Record<string, unknown>, propertyKey: string) {
|
|
71
|
-
const columnOptions: ColumnOptions = {
|
|
72
|
-
type: 'simple-array', // TypeORM handles this
|
|
73
|
-
...options,
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
return Column(columnOptions)(target, propertyKey);
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Create timestamp column with database-appropriate type
|
|
82
|
-
*
|
|
83
|
-
* @param options - Additional column options
|
|
84
|
-
* @returns Column decorator
|
|
85
|
-
*/
|
|
86
|
-
export function TimestampColumn(options?: Partial<ColumnOptions>) {
|
|
87
|
-
return function (target: Record<string, unknown>, propertyKey: string) {
|
|
88
|
-
const columnOptions: ColumnOptions = {
|
|
89
|
-
type: 'timestamp',
|
|
90
|
-
...options,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
return Column(columnOptions)(target, propertyKey);
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Create boolean column with database-appropriate type
|
|
99
|
-
*
|
|
100
|
-
* @param options - Additional column options
|
|
101
|
-
* @returns Column decorator
|
|
102
|
-
*/
|
|
103
|
-
export function BooleanColumn(options?: Partial<ColumnOptions>) {
|
|
104
|
-
return function (target: Record<string, unknown>, propertyKey: string) {
|
|
105
|
-
const columnOptions: ColumnOptions = {
|
|
106
|
-
type: 'boolean',
|
|
107
|
-
...options,
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
return Column(columnOptions)(target, propertyKey);
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Create integer column with database-appropriate type
|
|
116
|
-
*
|
|
117
|
-
* @param options - Additional column options
|
|
118
|
-
* @returns Column decorator
|
|
119
|
-
*/
|
|
120
|
-
export function IntegerColumn(options?: Partial<ColumnOptions>) {
|
|
121
|
-
return function (target: Record<string, unknown>, propertyKey: string) {
|
|
122
|
-
const columnOptions: ColumnOptions = {
|
|
123
|
-
type: 'int',
|
|
124
|
-
...options,
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
return Column(columnOptions)(target, propertyKey);
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Create varchar column with database-appropriate type
|
|
133
|
-
*
|
|
134
|
-
* @param length - Maximum length
|
|
135
|
-
* @param options - Additional column options
|
|
136
|
-
* @returns Column decorator
|
|
137
|
-
*/
|
|
138
|
-
export function VarcharColumn(length: number, options?: Partial<ColumnOptions>) {
|
|
139
|
-
return function (target: Record<string, unknown>, propertyKey: string) {
|
|
140
|
-
const columnOptions: ColumnOptions = {
|
|
141
|
-
type: 'varchar',
|
|
142
|
-
length,
|
|
143
|
-
...options,
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
return Column(columnOptions)(target, propertyKey);
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Create text column with database-appropriate type
|
|
152
|
-
*
|
|
153
|
-
* @param options - Additional column options
|
|
154
|
-
* @returns Column decorator
|
|
155
|
-
*/
|
|
156
|
-
export function TextColumn(options?: Partial<ColumnOptions>) {
|
|
157
|
-
return function (target: Record<string, unknown>, propertyKey: string) {
|
|
158
|
-
const columnOptions: ColumnOptions = {
|
|
159
|
-
type: 'text',
|
|
160
|
-
...options,
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
return Column(columnOptions)(target, propertyKey);
|
|
164
|
-
};
|
|
165
|
-
}
|
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Express Framework Adapter
|
|
3
|
-
*
|
|
4
|
-
* Adapts NAuth to work with Express.js (4.x and 5.x compatible).
|
|
5
|
-
*
|
|
6
|
-
* **Context Management:**
|
|
7
|
-
* - First middleware (clientInfo) initializes AsyncLocalStorage context
|
|
8
|
-
* - Context automatically propagates through Express middleware chain
|
|
9
|
-
* - Route handlers have automatic context access (no wrapper needed)
|
|
10
|
-
*
|
|
11
|
-
* **Express 5.x Compatibility:**
|
|
12
|
-
* - Uses req.hostname instead of deprecated req.host
|
|
13
|
-
* - Handles async middleware errors automatically
|
|
14
|
-
* - Compatible with new path matching behavior
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import {
|
|
18
|
-
NAuthAdapter,
|
|
19
|
-
NAuthRequest,
|
|
20
|
-
NAuthResponse,
|
|
21
|
-
NAuthCookieOptions,
|
|
22
|
-
NAuthRequestAttributes,
|
|
23
|
-
NAuthMiddlewareHandler,
|
|
24
|
-
NAuthResponseInterceptorHandler,
|
|
25
|
-
NAuthRouteHandler,
|
|
26
|
-
MiddlewareOptions,
|
|
27
|
-
} from '../platform/interfaces';
|
|
28
|
-
import { ContextStorage } from '../utils/context-storage';
|
|
29
|
-
|
|
30
|
-
// ============================================================================
|
|
31
|
-
// Express Adapter
|
|
32
|
-
// ============================================================================
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Express Adapter Implementation
|
|
36
|
-
*
|
|
37
|
-
* Provides NAuth integration for Express.js applications.
|
|
38
|
-
*/
|
|
39
|
-
export class ExpressAdapter implements NAuthAdapter {
|
|
40
|
-
public readonly name = 'ExpressAdapter';
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Register a middleware handler
|
|
44
|
-
*
|
|
45
|
-
* Wraps the generic NAuth handler into Express middleware format.
|
|
46
|
-
* Handles context initialization for the first middleware.
|
|
47
|
-
*/
|
|
48
|
-
public registerMiddleware(
|
|
49
|
-
name: string,
|
|
50
|
-
handler: NAuthMiddlewareHandler,
|
|
51
|
-
options?: MiddlewareOptions,
|
|
52
|
-
): ExpressMiddleware {
|
|
53
|
-
const initializesContext = options?.initializesContext || name === 'clientInfo';
|
|
54
|
-
|
|
55
|
-
return async (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction): Promise<void> => {
|
|
56
|
-
// Ensure we have attribute storage
|
|
57
|
-
if (!req._nauthAttributes) {
|
|
58
|
-
req._nauthAttributes = {};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const nauthReq = new ExpressRequestWrapper(req);
|
|
62
|
-
const nauthRes = new ExpressResponseWrapper(res);
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
if (initializesContext) {
|
|
66
|
-
// First middleware - initialize context
|
|
67
|
-
await ContextStorage.run(async () => {
|
|
68
|
-
await this.executeHandler(handler, nauthReq, nauthRes, next);
|
|
69
|
-
});
|
|
70
|
-
} else {
|
|
71
|
-
// Subsequent middleware - context should exist from first middleware
|
|
72
|
-
await this.executeHandler(handler, nauthReq, nauthRes, next);
|
|
73
|
-
}
|
|
74
|
-
} catch (error) {
|
|
75
|
-
next(error);
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Execute handler with proper async flow control
|
|
82
|
-
*/
|
|
83
|
-
private async executeHandler(
|
|
84
|
-
handler: NAuthMiddlewareHandler,
|
|
85
|
-
req: NAuthRequest,
|
|
86
|
-
res: NAuthResponse,
|
|
87
|
-
next: ExpressNextFunction,
|
|
88
|
-
): Promise<void> {
|
|
89
|
-
let nextCalled = false;
|
|
90
|
-
const nextError: unknown = undefined;
|
|
91
|
-
|
|
92
|
-
const wrappedNext = (): void => {
|
|
93
|
-
nextCalled = true;
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
await handler(req, res, wrappedNext);
|
|
97
|
-
|
|
98
|
-
// Only call Express next if handler called next and no response sent
|
|
99
|
-
if (nextCalled && !res.isSent()) {
|
|
100
|
-
next(nextError);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Register a response interceptor
|
|
106
|
-
*
|
|
107
|
-
* Uses res.json monkey-patching to intercept JSON responses.
|
|
108
|
-
* This is the standard pattern for Express response interception.
|
|
109
|
-
*/
|
|
110
|
-
public registerResponseInterceptor(handler: NAuthResponseInterceptorHandler): ExpressMiddleware {
|
|
111
|
-
return (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction): void => {
|
|
112
|
-
// Ensure we have attribute storage
|
|
113
|
-
if (!req._nauthAttributes) {
|
|
114
|
-
req._nauthAttributes = {};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const originalJson = res.json.bind(res);
|
|
118
|
-
|
|
119
|
-
// Monkey-patch res.json
|
|
120
|
-
res.json = function (body: unknown): ExpressResponse {
|
|
121
|
-
const nauthReq = new ExpressRequestWrapper(req);
|
|
122
|
-
const nauthRes = new ExpressResponseWrapper(res);
|
|
123
|
-
|
|
124
|
-
// Execute interceptor synchronously wrapped in promise handling
|
|
125
|
-
Promise.resolve(handler(nauthReq, nauthRes, body))
|
|
126
|
-
.then((modifiedBody) => {
|
|
127
|
-
// Restore original json to prevent recursion
|
|
128
|
-
res.json = originalJson;
|
|
129
|
-
return originalJson(modifiedBody);
|
|
130
|
-
})
|
|
131
|
-
.catch((error) => {
|
|
132
|
-
// On error, send original body (error handled gracefully)
|
|
133
|
-
res.json = originalJson;
|
|
134
|
-
return originalJson(body);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
// Return res for chaining (Express 5 style)
|
|
138
|
-
return res;
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
next();
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Wrap a route handler
|
|
147
|
-
*
|
|
148
|
-
* For Express, this provides:
|
|
149
|
-
* - NAuthRequest/NAuthResponse wrappers
|
|
150
|
-
* - Automatic error handling
|
|
151
|
-
* - Context is automatically available (no restoration needed)
|
|
152
|
-
*/
|
|
153
|
-
public wrapRouteHandler<T>(handler: NAuthRouteHandler<T>): ExpressMiddleware {
|
|
154
|
-
return async (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction): Promise<void> => {
|
|
155
|
-
// Ensure we have attribute storage
|
|
156
|
-
if (!req._nauthAttributes) {
|
|
157
|
-
req._nauthAttributes = {};
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const nauthReq = new ExpressRequestWrapper(req);
|
|
161
|
-
const nauthRes = new ExpressResponseWrapper(res);
|
|
162
|
-
|
|
163
|
-
try {
|
|
164
|
-
const result = await handler(nauthReq, nauthRes);
|
|
165
|
-
|
|
166
|
-
// If handler returned a value and response not sent, send it as JSON
|
|
167
|
-
if (result !== undefined && !res.headersSent) {
|
|
168
|
-
res.json(result);
|
|
169
|
-
}
|
|
170
|
-
} catch (error) {
|
|
171
|
-
next(error);
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// ============================================================================
|
|
178
|
-
// Express Request Wrapper
|
|
179
|
-
// ============================================================================
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Wraps Express request into NAuthRequest interface
|
|
183
|
-
*/
|
|
184
|
-
class ExpressRequestWrapper implements NAuthRequest {
|
|
185
|
-
constructor(private readonly req: ExpressRequest) {}
|
|
186
|
-
|
|
187
|
-
get raw(): unknown {
|
|
188
|
-
return this.req;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
get method(): string {
|
|
192
|
-
return this.req.method.toUpperCase();
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
get path(): string {
|
|
196
|
-
// Express provides path without query string
|
|
197
|
-
return this.req.path || this.req.url.split('?')[0];
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
get url(): string {
|
|
201
|
-
return this.req.originalUrl || this.req.url;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
get body(): Record<string, unknown> {
|
|
205
|
-
return (this.req.body as Record<string, unknown>) || {};
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
get query(): Record<string, unknown> {
|
|
209
|
-
return (this.req.query as Record<string, unknown>) || {};
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
get params(): Record<string, string> {
|
|
213
|
-
return (this.req.params as Record<string, string>) || {};
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
get headers(): Record<string, string | string[] | undefined> {
|
|
217
|
-
return this.req.headers as Record<string, string | string[] | undefined>;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
get cookies(): Record<string, string | undefined> {
|
|
221
|
-
// Express with cookie-parser middleware
|
|
222
|
-
return (this.req.cookies as Record<string, string | undefined>) || {};
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
get ip(): string {
|
|
226
|
-
// Express 4.x and 5.x compatible
|
|
227
|
-
// Trust proxy must be configured for X-Forwarded-For
|
|
228
|
-
return this.req.ip || this.req.socket?.remoteAddress || '0.0.0.0';
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
get attributes(): NAuthRequestAttributes {
|
|
232
|
-
// Return isolated storage, not raw request
|
|
233
|
-
return this.req._nauthAttributes || {};
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
public getHeader(name: string): string | undefined {
|
|
237
|
-
// Express provides req.get() for case-insensitive header lookup
|
|
238
|
-
const val = this.req.get ? this.req.get(name) : this.req.headers[name.toLowerCase()];
|
|
239
|
-
if (Array.isArray(val)) return val[0];
|
|
240
|
-
return val;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// ============================================================================
|
|
245
|
-
// Express Response Wrapper
|
|
246
|
-
// ============================================================================
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Wraps Express response into NAuthResponse interface
|
|
250
|
-
*/
|
|
251
|
-
class ExpressResponseWrapper implements NAuthResponse {
|
|
252
|
-
constructor(private readonly res: ExpressResponse) {}
|
|
253
|
-
|
|
254
|
-
get raw(): unknown {
|
|
255
|
-
return this.res;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
public status(code: number): this {
|
|
259
|
-
this.res.status(code);
|
|
260
|
-
return this;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
public header(name: string, value: string | string[]): this {
|
|
264
|
-
this.res.setHeader(name, value);
|
|
265
|
-
return this;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
public setCookie(name: string, value: string, options?: NAuthCookieOptions): this {
|
|
269
|
-
// Express provides res.cookie()
|
|
270
|
-
if (typeof this.res.cookie === 'function') {
|
|
271
|
-
this.res.cookie(name, value, this.convertCookieOptions(options));
|
|
272
|
-
}
|
|
273
|
-
return this;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
public clearCookie(name: string, options?: NAuthCookieOptions): this {
|
|
277
|
-
if (typeof this.res.clearCookie === 'function') {
|
|
278
|
-
this.res.clearCookie(name, this.convertCookieOptions(options));
|
|
279
|
-
}
|
|
280
|
-
return this;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
public send(body: unknown): void {
|
|
284
|
-
this.res.send(body);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
public json(body: unknown): void {
|
|
288
|
-
this.res.json(body);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
public redirect(url: string, status?: number): void {
|
|
292
|
-
if (status) {
|
|
293
|
-
this.res.redirect(status, url);
|
|
294
|
-
} else {
|
|
295
|
-
this.res.redirect(url);
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
public isSent(): boolean {
|
|
300
|
-
return this.res.headersSent;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Convert NAuth cookie options to Express cookie options
|
|
305
|
-
*/
|
|
306
|
-
private convertCookieOptions(options?: NAuthCookieOptions): Record<string, unknown> {
|
|
307
|
-
if (!options) return {};
|
|
308
|
-
|
|
309
|
-
return {
|
|
310
|
-
httpOnly: options.httpOnly,
|
|
311
|
-
secure: options.secure,
|
|
312
|
-
sameSite: options.sameSite,
|
|
313
|
-
domain: options.domain,
|
|
314
|
-
path: options.path,
|
|
315
|
-
maxAge: options.maxAge,
|
|
316
|
-
expires: options.expires,
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// ============================================================================
|
|
322
|
-
// Express Type Definitions (minimal, for internal use)
|
|
323
|
-
// ============================================================================
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Express Request type (minimal interface for our needs)
|
|
327
|
-
* Compatible with Express 4.x and 5.x
|
|
328
|
-
*/
|
|
329
|
-
interface ExpressRequest {
|
|
330
|
-
method: string;
|
|
331
|
-
path: string;
|
|
332
|
-
url: string;
|
|
333
|
-
originalUrl: string;
|
|
334
|
-
body: unknown;
|
|
335
|
-
query: unknown;
|
|
336
|
-
params: unknown;
|
|
337
|
-
headers: Record<string, string | string[] | undefined>;
|
|
338
|
-
cookies?: Record<string, string>;
|
|
339
|
-
ip: string;
|
|
340
|
-
socket?: { remoteAddress?: string };
|
|
341
|
-
get?(name: string): string | undefined;
|
|
342
|
-
|
|
343
|
-
/** NAuth attribute storage - isolated from raw request */
|
|
344
|
-
_nauthAttributes?: NAuthRequestAttributes;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* Express Response type (minimal interface for our needs)
|
|
349
|
-
* Compatible with Express 4.x and 5.x
|
|
350
|
-
*/
|
|
351
|
-
interface ExpressResponse {
|
|
352
|
-
status(code: number): this;
|
|
353
|
-
setHeader(name: string, value: string | string[]): void;
|
|
354
|
-
cookie(name: string, value: string, options?: Record<string, unknown>): void;
|
|
355
|
-
clearCookie(name: string, options?: Record<string, unknown>): void;
|
|
356
|
-
send(body: unknown): void;
|
|
357
|
-
json(body: unknown): this;
|
|
358
|
-
redirect(status: number, url: string): void;
|
|
359
|
-
redirect(url: string): void;
|
|
360
|
-
headersSent: boolean;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Express NextFunction type
|
|
365
|
-
*/
|
|
366
|
-
type ExpressNextFunction = (err?: unknown) => void;
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Express middleware signature
|
|
370
|
-
*/
|
|
371
|
-
type ExpressMiddleware = (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void | Promise<void>;
|
|
372
|
-
|
|
373
|
-
// ============================================================================
|
|
374
|
-
// Type Exports for Consumer Applications
|
|
375
|
-
// ============================================================================
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Express middleware type for use with app.use()
|
|
379
|
-
*
|
|
380
|
-
* Consumer apps should cast nauth.middleware.* to this type:
|
|
381
|
-
* ```typescript
|
|
382
|
-
* app.use(nauth.middleware.clientInfo as ExpressMiddlewareType);
|
|
383
|
-
* ```
|
|
384
|
-
*/
|
|
385
|
-
export type ExpressMiddlewareType = (req: unknown, res: unknown, next: (err?: unknown) => void) => void | Promise<void>;
|