@plyaz/auth 1.0.0
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/.github/pull_request_template.md +71 -0
- package/.github/workflows/deploy.yml +9 -0
- package/.github/workflows/publish.yml +14 -0
- package/.github/workflows/security.yml +20 -0
- package/README.md +89 -0
- package/commits.txt +5 -0
- package/dist/common/index.cjs +48 -0
- package/dist/common/index.cjs.map +1 -0
- package/dist/common/index.mjs +43 -0
- package/dist/common/index.mjs.map +1 -0
- package/dist/index.cjs +20411 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +5139 -0
- package/dist/index.mjs.map +1 -0
- package/eslint.config.mjs +13 -0
- package/index.html +13 -0
- package/package.json +141 -0
- package/src/adapters/auth-adapter-factory.ts +26 -0
- package/src/adapters/auth-adapter.mapper.ts +53 -0
- package/src/adapters/base-auth.adapter.ts +119 -0
- package/src/adapters/clerk/clerk.adapter.ts +204 -0
- package/src/adapters/custom/custom.adapter.ts +119 -0
- package/src/adapters/index.ts +4 -0
- package/src/adapters/next-auth/authOptions.ts +81 -0
- package/src/adapters/next-auth/next-auth.adapter.ts +211 -0
- package/src/api/client.ts +37 -0
- package/src/audit/audit.logger.ts +52 -0
- package/src/client/components/ProtectedRoute.tsx +37 -0
- package/src/client/hooks/useAuth.ts +128 -0
- package/src/client/hooks/useConnectedAccounts.ts +108 -0
- package/src/client/hooks/usePermissions.ts +36 -0
- package/src/client/hooks/useRBAC.ts +36 -0
- package/src/client/hooks/useSession.ts +18 -0
- package/src/client/providers/AuthProvider.tsx +104 -0
- package/src/client/store/auth.store.ts +306 -0
- package/src/client/utils/storage.ts +70 -0
- package/src/common/constants/oauth-providers.ts +49 -0
- package/src/common/errors/auth.errors.ts +64 -0
- package/src/common/errors/specific-auth-errors.ts +201 -0
- package/src/common/index.ts +19 -0
- package/src/common/regex/index.ts +27 -0
- package/src/common/types/auth.types.ts +641 -0
- package/src/common/types/index.ts +297 -0
- package/src/common/utils/index.ts +84 -0
- package/src/core/blacklist/token.blacklist.ts +60 -0
- package/src/core/index.ts +2 -0
- package/src/core/jwt/jwt.manager.ts +131 -0
- package/src/core/session/session.manager.ts +56 -0
- package/src/db/repositories/connected-account.repository.ts +415 -0
- package/src/db/repositories/role.repository.ts +519 -0
- package/src/db/repositories/session.repository.ts +308 -0
- package/src/db/repositories/user.repository.ts +320 -0
- package/src/flows/index.ts +2 -0
- package/src/flows/sign-in.flow.ts +106 -0
- package/src/flows/sign-up.flow.ts +121 -0
- package/src/index.ts +54 -0
- package/src/libs/clerk.helper.ts +36 -0
- package/src/libs/supabase.helper.ts +255 -0
- package/src/libs/supabaseClient.ts +6 -0
- package/src/providers/base/auth-provider.interface.ts +42 -0
- package/src/providers/base/index.ts +1 -0
- package/src/providers/index.ts +2 -0
- package/src/providers/oauth/facebook.provider.ts +97 -0
- package/src/providers/oauth/github.provider.ts +148 -0
- package/src/providers/oauth/google.provider.ts +126 -0
- package/src/providers/oauth/index.ts +3 -0
- package/src/rbac/dynamic-roles.ts +552 -0
- package/src/rbac/index.ts +4 -0
- package/src/rbac/permission-checker.ts +464 -0
- package/src/rbac/role-hierarchy.ts +545 -0
- package/src/rbac/role.manager.ts +75 -0
- package/src/security/csrf/csrf.protection.ts +37 -0
- package/src/security/index.ts +3 -0
- package/src/security/rate-limiting/auth/auth.controller.ts +12 -0
- package/src/security/rate-limiting/auth/rate-limiting.interface.ts +67 -0
- package/src/security/rate-limiting/auth.module.ts +32 -0
- package/src/server/auth.module.ts +158 -0
- package/src/server/decorators/auth.decorator.ts +43 -0
- package/src/server/decorators/auth.decorators.ts +31 -0
- package/src/server/decorators/current-user.decorator.ts +49 -0
- package/src/server/decorators/permission.decorator.ts +49 -0
- package/src/server/guards/auth.guard.ts +56 -0
- package/src/server/guards/custom-throttler.guard.ts +46 -0
- package/src/server/guards/permissions.guard.ts +115 -0
- package/src/server/guards/roles.guard.ts +31 -0
- package/src/server/middleware/auth.middleware.ts +46 -0
- package/src/server/middleware/index.ts +2 -0
- package/src/server/middleware/middleware.ts +11 -0
- package/src/server/middleware/session.middleware.ts +255 -0
- package/src/server/services/account.service.ts +269 -0
- package/src/server/services/auth.service.ts +79 -0
- package/src/server/services/brute-force.service.ts +98 -0
- package/src/server/services/index.ts +15 -0
- package/src/server/services/rate-limiter.service.ts +60 -0
- package/src/server/services/session.service.ts +287 -0
- package/src/server/services/token.service.ts +262 -0
- package/src/session/cookie-store.ts +255 -0
- package/src/session/enhanced-session-manager.ts +406 -0
- package/src/session/index.ts +14 -0
- package/src/session/memory-store.ts +320 -0
- package/src/session/redis-store.ts +443 -0
- package/src/strategies/oauth.strategy.ts +128 -0
- package/src/strategies/traditional-auth.strategy.ts +116 -0
- package/src/tokens/index.ts +4 -0
- package/src/tokens/refresh-token-manager.ts +448 -0
- package/src/tokens/token-validator.ts +311 -0
- package/tsconfig.build.json +28 -0
- package/tsconfig.json +38 -0
- package/tsup.config.mjs +28 -0
- package/vitest.config.mjs +16 -0
- package/vitest.setup.d.ts +2 -0
- package/vitest.setup.d.ts.map +1 -0
- package/vitest.setup.ts +1 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Pull Request Template
|
|
2
|
+
|
|
3
|
+
## Jira Ticket
|
|
4
|
+
|
|
5
|
+
- **Ticket**: [PLYENG-XXX](https://plyaz.atlassian.net/browse/PLYAZ-XXX)
|
|
6
|
+
- **Epic**: [PLYENG-XXX](https://plyaz.atlassian.net/browse/PLYAZ-XXX) (if applicable)
|
|
7
|
+
|
|
8
|
+
## Type of Change
|
|
9
|
+
|
|
10
|
+
- [ ] 🐛 Bug fix (non-breaking change that fixes an issue)
|
|
11
|
+
- [ ] ✨ New feature (non-breaking change that adds functionality)
|
|
12
|
+
- [ ] 💥 Breaking change (fix or feature with API changes or that would cause existing functionality to not work as expected)
|
|
13
|
+
- [ ] 🔨 Refactoring (code improvement with no functional changes)
|
|
14
|
+
- [ ] 📚 Documentation update
|
|
15
|
+
- [ ] 🧪 Test update
|
|
16
|
+
- [ ] 🛠️ Build/CI update
|
|
17
|
+
- [ ] 🧹 Chore (dependency updates, maintenance tasks, etc.)
|
|
18
|
+
|
|
19
|
+
## Approval Checklist
|
|
20
|
+
|
|
21
|
+
All pull requests must satisfy the following criteria before being considered for approval:
|
|
22
|
+
|
|
23
|
+
### 1. Tests
|
|
24
|
+
|
|
25
|
+
- [ ] New tests added for all new functionality
|
|
26
|
+
- [ ] Minimum 90% test coverage for modified code
|
|
27
|
+
- [ ] All existing tests passing without failures
|
|
28
|
+
- [ ] Edge cases and error conditions properly tested
|
|
29
|
+
|
|
30
|
+
### 2. Documentation
|
|
31
|
+
|
|
32
|
+
- [ ] Code is properly documented with JSDoc comments
|
|
33
|
+
- [ ] README files updated if necessary
|
|
34
|
+
- [ ] Architecture documentation updated for structural changes before any code written
|
|
35
|
+
- [ ] Storybook entries created/updated for UI components
|
|
36
|
+
- [ ] API endpoints documented if modified or added
|
|
37
|
+
- [ ] Ensure that the architecture has to be updated or created on the respective stack:
|
|
38
|
+
- [Backend](https://plyaz.atlassian.net/wiki/spaces/SD/folder/950466)
|
|
39
|
+
- [Frontend](https://plyaz.atlassian.net/wiki/spaces/SD/folder/655573)
|
|
40
|
+
- [Blockchain](https://plyaz.atlassian.net/wiki/spaces/SD/folder/753881)
|
|
41
|
+
- [Infrastructure](https://plyaz.atlassian.net/wiki/spaces/SD/folder/4096013)
|
|
42
|
+
|
|
43
|
+
### 3. Quality
|
|
44
|
+
|
|
45
|
+
- [ ] No linting errors or warnings (ESLint/TSLint)
|
|
46
|
+
- [ ] Proper code formatting (Prettier)
|
|
47
|
+
- [ ] TypeScript types properly defined and used
|
|
48
|
+
- [ ] No code smells or anti-patterns
|
|
49
|
+
- [ ] Adherence to project coding standards
|
|
50
|
+
- [ ] Responsive design for frontend components
|
|
51
|
+
|
|
52
|
+
### 4. Review
|
|
53
|
+
|
|
54
|
+
- [ ] At least one approval from another developer
|
|
55
|
+
- [ ] All review comments addressed with changes or explanations
|
|
56
|
+
- [ ] Critical changes require architect approval
|
|
57
|
+
- [ ] Security-sensitive changes require CTO approval
|
|
58
|
+
|
|
59
|
+
### 5. Dependencies
|
|
60
|
+
|
|
61
|
+
- [ ] No unnecessary dependencies added
|
|
62
|
+
- [ ] Dependencies audited for security vulnerabilities
|
|
63
|
+
- [ ] Package versions follow our version policy
|
|
64
|
+
- [ ] Impact on bundle size assessed for frontend dependencies
|
|
65
|
+
|
|
66
|
+
### 6. Performance
|
|
67
|
+
|
|
68
|
+
- [ ] No obvious performance issues introduced
|
|
69
|
+
- [ ] Database queries optimized for efficiency
|
|
70
|
+
- [ ] Frontend components optimized for rendering performance
|
|
71
|
+
- [ ] API endpoints respond within expected timeframes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
name: Publish Package
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: write # Required for pushing version bumps and tags
|
|
8
|
+
packages: write # Required for publishing packages
|
|
9
|
+
pull-requests: read # Required for reading PR information
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
uses: Plyaz-Official/devtools/.github/workflows/publish.yml@main
|
|
14
|
+
secrets: inherit
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Security
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main, dev, staging]
|
|
5
|
+
pull_request:
|
|
6
|
+
branches: [main, dev, staging]
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
pull-requests: write # Required for posting dependency review comments
|
|
11
|
+
security-events: write # Required for OSV-Scanner SARIF uploads
|
|
12
|
+
actions: read # Required for OSV-Scanner
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
security:
|
|
16
|
+
uses: Plyaz-Official/devtools/.github/workflows/security.yml@main
|
|
17
|
+
with:
|
|
18
|
+
skip_osv_scan: true
|
|
19
|
+
dependency_review: false
|
|
20
|
+
secrets: inherit
|
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @plyaz/auth
|
|
2
|
+
|
|
3
|
+
A shared authentication package for the Plyaz ecosystem. This library centralizes core authentication strategies, provider integrations, and access control logic, ensuring that all applications within our monorepo share a single, consistent source of truth for user sessions and permissions.
|
|
4
|
+
|
|
5
|
+
## 📦 Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @plyaz/auth
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 🚀 What's Included
|
|
12
|
+
|
|
13
|
+
### Core Features
|
|
14
|
+
|
|
15
|
+
- **Authentication Strategies** - Support for multiple authentication flows, including email/password, social logins, and token-based authentication (JWT, API keys).
|
|
16
|
+
- **Provider Abstractions** - Standardized interfaces for integrating with external providers like Clerk, OAuth services, and other third-party authentication platforms.
|
|
17
|
+
- **Role-Based Access Control (RBAC)** - A robust system for managing user roles and permissions, enabling granular control over application features.
|
|
18
|
+
- **Session Management** - Secure and unified session handling across all Plyaz applications.
|
|
19
|
+
- **Ecosystem Integration** - Seamlessly integrates with @plyaz/types, @plyaz/config, and other shared packages.
|
|
20
|
+
|
|
21
|
+
## Development
|
|
22
|
+
|
|
23
|
+
### Setup
|
|
24
|
+
|
|
25
|
+
Install dependencies and run the basic checks:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm install
|
|
29
|
+
pnpm lint
|
|
30
|
+
pnpm test
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Build
|
|
34
|
+
|
|
35
|
+
Compile the library to the dist folder:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pnpm build
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
For a watch mode during development:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pnpm dev
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Linting & Formatting
|
|
48
|
+
|
|
49
|
+
Run the ESLint rules and apply automatic fixes:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pnpm lint
|
|
53
|
+
pnpm lint:fix
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Check or apply Prettier formatting:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pnpm format:check
|
|
60
|
+
pnpm format
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Tests
|
|
64
|
+
|
|
65
|
+
Execute the test suite once:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pnpm test
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Watch tests as you work:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pnpm test:watch
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Generate coverage information:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pnpm test:coverage
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Relationship to Plyaz-Official/types
|
|
84
|
+
|
|
85
|
+
Type definitions for authentication values, like User, Role, and Permission, live in [Plyaz-Official/types](https://github.com/Plyaz-Official/types). Installing @plyaz/types alongside this package provides strongly typed access to each exported constant and type.
|
|
86
|
+
|
|
87
|
+
## About this repository
|
|
88
|
+
|
|
89
|
+
This package was scaffolded from the internal package-template and relies on [@plyaz/devtools](https://www.npmjs.com/package/@plyaz/devtools) for shared TypeScript, ESLint, Prettier, and Vitest configuration.
|
package/commits.txt
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var config = require('@plyaz/config');
|
|
4
|
+
|
|
5
|
+
// @plyaz package - Built with tsup
|
|
6
|
+
var __defProp = Object.defineProperty;
|
|
7
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
8
|
+
function generateRandomString(length = 32) {
|
|
9
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
10
|
+
let result = "";
|
|
11
|
+
for (let i = 0; i < length; i++) {
|
|
12
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
__name(generateRandomString, "generateRandomString");
|
|
17
|
+
function generateSecureId() {
|
|
18
|
+
return `${Date.now()}_${generateRandomString(config.NUMERIX.SIXTEEN)}`;
|
|
19
|
+
}
|
|
20
|
+
__name(generateSecureId, "generateSecureId");
|
|
21
|
+
function sleep(ms) {
|
|
22
|
+
return new Promise((resolve) => globalThis.setTimeout(resolve, ms));
|
|
23
|
+
}
|
|
24
|
+
__name(sleep, "sleep");
|
|
25
|
+
function maskSensitiveData(data, sensitiveFields = ["password", "token", "secret"]) {
|
|
26
|
+
if (typeof data !== "object" || data === null) {
|
|
27
|
+
return data;
|
|
28
|
+
}
|
|
29
|
+
const masked = { ...data };
|
|
30
|
+
const four = 4;
|
|
31
|
+
for (const field of sensitiveFields) {
|
|
32
|
+
if (field in masked) {
|
|
33
|
+
const value = masked[field];
|
|
34
|
+
if (typeof value === "string" && value.length > 0) {
|
|
35
|
+
masked[field] = value.substring(0, four) + "*".repeat(Math.max(0, value.length - four));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return masked;
|
|
40
|
+
}
|
|
41
|
+
__name(maskSensitiveData, "maskSensitiveData");
|
|
42
|
+
|
|
43
|
+
exports.generateRandomString = generateRandomString;
|
|
44
|
+
exports.generateSecureId = generateSecureId;
|
|
45
|
+
exports.maskSensitiveData = maskSensitiveData;
|
|
46
|
+
exports.sleep = sleep;
|
|
47
|
+
//# sourceMappingURL=index.cjs.map
|
|
48
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/common/utils/index.ts"],"names":["NUMERIX"],"mappings":";;;;;;;AAgBO,SAAS,oBAAA,CAAqB,SAAiB,EAAA,EAAY;AAChE,EAAA,MAAM,KAAA,GAAQ,gEAAA;AACd,EAAA,IAAI,MAAA,GAAS,EAAA;AACb,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAC/B,IAAA,MAAA,IAAU,KAAA,CAAM,OAAO,IAAA,CAAK,KAAA,CAAM,KAAK,MAAA,EAAO,GAAI,KAAA,CAAM,MAAM,CAAC,CAAA;AAAA,EACjE;AACA,EAAA,OAAO,MAAA;AACT;AAPgB,MAAA,CAAA,oBAAA,EAAA,sBAAA,CAAA;AAiBT,SAAS,gBAAA,GAA2B;AACzC,EAAA,OAAO,CAAA,EAAG,KAAK,GAAA,EAAK,IAAI,oBAAA,CAAqBA,cAAA,CAAQ,OAAO,CAAC,CAAA,CAAA;AAC/D;AAFgB,MAAA,CAAA,gBAAA,EAAA,kBAAA,CAAA;AAaT,SAAS,MAAM,EAAA,EAA2B;AAC/C,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAA,OAAA,KAAW,WAAW,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AAClE;AAFgB,MAAA,CAAA,KAAA,EAAA,OAAA,CAAA;AAeT,SAAS,kBACd,IAAA,EACA,eAAA,GAA4B,CAAC,UAAA,EAAY,OAAA,EAAS,QAAQ,CAAA,EACjD;AACT,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,IAAA,EAAM;AAC7C,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,MAAA,GAAiC,EAAE,GAAI,IAAA,EAAgC;AAC7E,EAAA,MAAM,IAAA,GAAQ,CAAA;AACd,EAAA,KAAA,MAAW,SAAS,eAAA,EAAiB;AACnC,IAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,MAAA,MAAM,KAAA,GAAQ,OAAO,KAAK,CAAA;AAC1B,MAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,SAAS,CAAA,EAAG;AACjD,QAAA,MAAA,CAAO,KAAK,CAAA,GAAI,KAAA,CAAM,SAAA,CAAU,GAAG,IAAI,CAAA,GAAI,GAAA,CAAI,MAAA,CAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,MAAA,GAAS,IAAI,CAAC,CAAA;AAAA,MACxF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AArBgB,MAAA,CAAA,iBAAA,EAAA,mBAAA,CAAA","file":"index.cjs","sourcesContent":["/**\n * @fileoverview Common utility functions for @plyaz/auth\n * @module @plyaz/auth/common/utils\n */\n\nimport { NUMERIX } from \"@plyaz/config\";\n\n/**\n * Generate a random string of specified length using alphanumeric characters\n * @param length - Length of the random string (default: 32)\n * @returns Random alphanumeric string\n * @example\n * ```typescript\n * const randomId = generateRandomString(16); // \"a1B2c3D4e5F6g7H8\"\n * ```\n */\nexport function generateRandomString(length: number = 32): string {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n\n/**\n * Generate a cryptographically secure random ID with timestamp prefix\n * @returns Unique identifier with timestamp and random suffix\n * @example\n * ```typescript\n * const id = generateSecureId(); // \"1703123456789_a1B2c3D4e5F6g7H8\"\n * ```\n */\nexport function generateSecureId(): string {\n return `${Date.now()}_${generateRandomString(NUMERIX.SIXTEEN)}`;\n}\n\n/**\n * Sleep for specified milliseconds (async delay)\n * @param ms - Milliseconds to sleep\n * @returns Promise that resolves after the delay\n * @example\n * ```typescript\n * await sleep(1000); // Wait 1 second\n * ```\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => globalThis.setTimeout(resolve, ms));\n}\n\n/**\n * Mask sensitive data fields for safe logging\n * @param data - Object containing potentially sensitive data\n * @param sensitiveFields - Array of field names to mask (default: ['password', 'token', 'secret'])\n * @returns Object with sensitive fields masked\n * @example\n * ```typescript\n * const masked = maskSensitiveData({ email: 'user@example.com', password: 'secret123' });\n * // Result: { email: 'user@example.com', password: 'secr*****' }\n * ```\n */\nexport function maskSensitiveData(\n data: unknown,\n sensitiveFields: string[] = ['password', 'token', 'secret']\n): unknown {\n if (typeof data !== 'object' || data === null) {\n return data;\n }\n\n // Type assertion to allow indexing by string\n const masked: Record<string, string> = { ...(data as Record<string, string>) };\n const four = 4;\n for (const field of sensitiveFields) {\n if (field in masked) {\n const value = masked[field];\n if (typeof value === 'string' && value.length > 0) {\n masked[field] = value.substring(0, four) + '*'.repeat(Math.max(0, value.length - four));\n }\n }\n }\n \n return masked;\n}\n\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { NUMERIX } from '@plyaz/config';
|
|
2
|
+
|
|
3
|
+
// @plyaz package - Built with tsup
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
+
function generateRandomString(length = 32) {
|
|
7
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
8
|
+
let result = "";
|
|
9
|
+
for (let i = 0; i < length; i++) {
|
|
10
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
11
|
+
}
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
14
|
+
__name(generateRandomString, "generateRandomString");
|
|
15
|
+
function generateSecureId() {
|
|
16
|
+
return `${Date.now()}_${generateRandomString(NUMERIX.SIXTEEN)}`;
|
|
17
|
+
}
|
|
18
|
+
__name(generateSecureId, "generateSecureId");
|
|
19
|
+
function sleep(ms) {
|
|
20
|
+
return new Promise((resolve) => globalThis.setTimeout(resolve, ms));
|
|
21
|
+
}
|
|
22
|
+
__name(sleep, "sleep");
|
|
23
|
+
function maskSensitiveData(data, sensitiveFields = ["password", "token", "secret"]) {
|
|
24
|
+
if (typeof data !== "object" || data === null) {
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
27
|
+
const masked = { ...data };
|
|
28
|
+
const four = 4;
|
|
29
|
+
for (const field of sensitiveFields) {
|
|
30
|
+
if (field in masked) {
|
|
31
|
+
const value = masked[field];
|
|
32
|
+
if (typeof value === "string" && value.length > 0) {
|
|
33
|
+
masked[field] = value.substring(0, four) + "*".repeat(Math.max(0, value.length - four));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return masked;
|
|
38
|
+
}
|
|
39
|
+
__name(maskSensitiveData, "maskSensitiveData");
|
|
40
|
+
|
|
41
|
+
export { generateRandomString, generateSecureId, maskSensitiveData, sleep };
|
|
42
|
+
//# sourceMappingURL=index.mjs.map
|
|
43
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/common/utils/index.ts"],"names":[],"mappings":";;;;;AAgBO,SAAS,oBAAA,CAAqB,SAAiB,EAAA,EAAY;AAChE,EAAA,MAAM,KAAA,GAAQ,gEAAA;AACd,EAAA,IAAI,MAAA,GAAS,EAAA;AACb,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAC/B,IAAA,MAAA,IAAU,KAAA,CAAM,OAAO,IAAA,CAAK,KAAA,CAAM,KAAK,MAAA,EAAO,GAAI,KAAA,CAAM,MAAM,CAAC,CAAA;AAAA,EACjE;AACA,EAAA,OAAO,MAAA;AACT;AAPgB,MAAA,CAAA,oBAAA,EAAA,sBAAA,CAAA;AAiBT,SAAS,gBAAA,GAA2B;AACzC,EAAA,OAAO,CAAA,EAAG,KAAK,GAAA,EAAK,IAAI,oBAAA,CAAqB,OAAA,CAAQ,OAAO,CAAC,CAAA,CAAA;AAC/D;AAFgB,MAAA,CAAA,gBAAA,EAAA,kBAAA,CAAA;AAaT,SAAS,MAAM,EAAA,EAA2B;AAC/C,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAA,OAAA,KAAW,WAAW,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AAClE;AAFgB,MAAA,CAAA,KAAA,EAAA,OAAA,CAAA;AAeT,SAAS,kBACd,IAAA,EACA,eAAA,GAA4B,CAAC,UAAA,EAAY,OAAA,EAAS,QAAQ,CAAA,EACjD;AACT,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,IAAA,EAAM;AAC7C,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,MAAA,GAAiC,EAAE,GAAI,IAAA,EAAgC;AAC7E,EAAA,MAAM,IAAA,GAAQ,CAAA;AACd,EAAA,KAAA,MAAW,SAAS,eAAA,EAAiB;AACnC,IAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,MAAA,MAAM,KAAA,GAAQ,OAAO,KAAK,CAAA;AAC1B,MAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,SAAS,CAAA,EAAG;AACjD,QAAA,MAAA,CAAO,KAAK,CAAA,GAAI,KAAA,CAAM,SAAA,CAAU,GAAG,IAAI,CAAA,GAAI,GAAA,CAAI,MAAA,CAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,MAAA,GAAS,IAAI,CAAC,CAAA;AAAA,MACxF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AArBgB,MAAA,CAAA,iBAAA,EAAA,mBAAA,CAAA","file":"index.mjs","sourcesContent":["/**\n * @fileoverview Common utility functions for @plyaz/auth\n * @module @plyaz/auth/common/utils\n */\n\nimport { NUMERIX } from \"@plyaz/config\";\n\n/**\n * Generate a random string of specified length using alphanumeric characters\n * @param length - Length of the random string (default: 32)\n * @returns Random alphanumeric string\n * @example\n * ```typescript\n * const randomId = generateRandomString(16); // \"a1B2c3D4e5F6g7H8\"\n * ```\n */\nexport function generateRandomString(length: number = 32): string {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n\n/**\n * Generate a cryptographically secure random ID with timestamp prefix\n * @returns Unique identifier with timestamp and random suffix\n * @example\n * ```typescript\n * const id = generateSecureId(); // \"1703123456789_a1B2c3D4e5F6g7H8\"\n * ```\n */\nexport function generateSecureId(): string {\n return `${Date.now()}_${generateRandomString(NUMERIX.SIXTEEN)}`;\n}\n\n/**\n * Sleep for specified milliseconds (async delay)\n * @param ms - Milliseconds to sleep\n * @returns Promise that resolves after the delay\n * @example\n * ```typescript\n * await sleep(1000); // Wait 1 second\n * ```\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => globalThis.setTimeout(resolve, ms));\n}\n\n/**\n * Mask sensitive data fields for safe logging\n * @param data - Object containing potentially sensitive data\n * @param sensitiveFields - Array of field names to mask (default: ['password', 'token', 'secret'])\n * @returns Object with sensitive fields masked\n * @example\n * ```typescript\n * const masked = maskSensitiveData({ email: 'user@example.com', password: 'secret123' });\n * // Result: { email: 'user@example.com', password: 'secr*****' }\n * ```\n */\nexport function maskSensitiveData(\n data: unknown,\n sensitiveFields: string[] = ['password', 'token', 'secret']\n): unknown {\n if (typeof data !== 'object' || data === null) {\n return data;\n }\n\n // Type assertion to allow indexing by string\n const masked: Record<string, string> = { ...(data as Record<string, string>) };\n const four = 4;\n for (const field of sensitiveFields) {\n if (field in masked) {\n const value = masked[field];\n if (typeof value === 'string' && value.length > 0) {\n masked[field] = value.substring(0, four) + '*'.repeat(Math.max(0, value.length - four));\n }\n }\n }\n \n return masked;\n}\n\n"]}
|