ace-auth 1.0.0 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -35
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
# 🛡️
|
|
1
|
+
# 🛡️ AceAuth
|
|
2
2
|
|
|
3
3
|
> **Stateful Security, Stateless Speed.**
|
|
4
4
|
> An enterprise-grade identity management library featuring "Graceful Token Rotation," Device Fingerprinting, and Sliding Window sessions.
|
|
5
5
|
|
|
6
|
-
[](https://www.npmjs.com/package/ace-auth)
|
|
7
7
|

|
|
8
8
|

|
|
9
9
|

|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
## 💡 Why
|
|
13
|
+
## 💡 Why AceAuth?
|
|
14
14
|
|
|
15
15
|
In modern web development, you typically have to choose between **Security** (short-lived JWTs) and **User Experience** (long-lived sessions).
|
|
16
16
|
|
|
17
|
-
**
|
|
17
|
+
**AceAuth gives you both.** It uses a **Hybrid Architecture** to maintain security without forcing users to log in repeatedly.
|
|
18
18
|
|
|
19
|
-
| Feature | Standard JWT
|
|
20
|
-
|
|
21
|
-
| **Revocation** | ❌ Impossible until expiry
|
|
22
|
-
| **Performance** | ✅ High (Stateless)
|
|
23
|
-
| **UX** | ❌ Hard Logout on expiry
|
|
24
|
-
| **Device Mgmt** | ❌ None
|
|
19
|
+
| Feature | Standard JWT | AceAuth |
|
|
20
|
+
|------------------|-------------------------------|-----------------------------|
|
|
21
|
+
| **Revocation** | ❌ Impossible until expiry | ✅ **Instant** (DB Backed) |
|
|
22
|
+
| **Performance** | ✅ High (Stateless) | ✅ **High** (Redis Caching) |
|
|
23
|
+
| **UX** | ❌ Hard Logout on expiry | ✅ **Graceful Auto-Rotation** |
|
|
24
|
+
| **Device Mgmt** | ❌ None | ✅ **Active Sessions View** |
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
28
28
|
## 📦 Installation
|
|
29
29
|
|
|
30
|
-
Install
|
|
30
|
+
Install AceAuth via npm:
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
npm install
|
|
33
|
+
npm install ace-auth
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
---
|
|
@@ -39,10 +39,10 @@ npm install @namra_ace/zen-auth
|
|
|
39
39
|
|
|
40
40
|
### 1. Initialize
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
AceAuth is database-agnostic. Below is a standard production setup using Redis:
|
|
43
43
|
|
|
44
44
|
```typescript
|
|
45
|
-
import {
|
|
45
|
+
import { AceAuth, RedisStore } from 'ace-auth';
|
|
46
46
|
import { createClient } from 'redis';
|
|
47
47
|
|
|
48
48
|
// 1. Connect to Redis
|
|
@@ -50,7 +50,7 @@ const redis = createClient();
|
|
|
50
50
|
await redis.connect();
|
|
51
51
|
|
|
52
52
|
// 2. Initialize Auth Engine
|
|
53
|
-
const auth = new
|
|
53
|
+
const auth = new AceAuth({
|
|
54
54
|
secret: process.env.JWT_SECRET || 'super-secret',
|
|
55
55
|
store: new RedisStore(redis),
|
|
56
56
|
sessionDuration: 30 * 24 * 60 * 60, // 30 Days (Sliding Window)
|
|
@@ -62,11 +62,9 @@ const auth = new ZenAuth({
|
|
|
62
62
|
});
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
---
|
|
66
|
-
|
|
67
65
|
### 2. Login (Capture Device Info)
|
|
68
66
|
|
|
69
|
-
Pass the request object (`req`) so
|
|
67
|
+
Pass the request object (`req`) so AceAuth can fingerprint the device (IP/User-Agent).
|
|
70
68
|
|
|
71
69
|
```typescript
|
|
72
70
|
import express from 'express';
|
|
@@ -83,17 +81,15 @@ app.post('/api/login', async (req, res) => {
|
|
|
83
81
|
});
|
|
84
82
|
```
|
|
85
83
|
|
|
86
|
-
---
|
|
87
|
-
|
|
88
84
|
### 3. Protect Routes (Middleware)
|
|
89
85
|
|
|
90
|
-
Use the included
|
|
86
|
+
Use the included gatekeeper middleware to secure endpoints. It automatically handles Graceful Expiration.
|
|
91
87
|
|
|
92
88
|
```typescript
|
|
93
|
-
import { gatekeeper } from '
|
|
89
|
+
import { gatekeeper } from 'ace-auth/middleware';
|
|
94
90
|
|
|
95
91
|
app.get('/api/profile', gatekeeper(auth), (req, res) => {
|
|
96
|
-
// If token was rotated, the new one is in res.headers['x-
|
|
92
|
+
// If token was rotated, the new one is in res.headers['x-ace-token']
|
|
97
93
|
res.json({ message: `Hello User ${req.user.id}` });
|
|
98
94
|
});
|
|
99
95
|
```
|
|
@@ -102,14 +98,14 @@ app.get('/api/profile', gatekeeper(auth), (req, res) => {
|
|
|
102
98
|
|
|
103
99
|
## 🔌 Database Adapters
|
|
104
100
|
|
|
105
|
-
|
|
101
|
+
AceAuth works with any database. Import the specific adapter you need.
|
|
106
102
|
|
|
107
103
|
### Redis (Recommended for Speed)
|
|
108
104
|
|
|
109
105
|
Uses Secondary Indexing (Sets) to map Users ↔ Sessions for O(1) lookups.
|
|
110
106
|
|
|
111
107
|
```typescript
|
|
112
|
-
import { RedisStore } from '
|
|
108
|
+
import { RedisStore } from 'ace-auth/adapters';
|
|
113
109
|
// Requires 'redis' package installed
|
|
114
110
|
const store = new RedisStore(redisClient);
|
|
115
111
|
```
|
|
@@ -119,7 +115,7 @@ const store = new RedisStore(redisClient);
|
|
|
119
115
|
Requires a table with columns: `sid` (text), `sess` (json), `expired_at` (timestamp).
|
|
120
116
|
|
|
121
117
|
```typescript
|
|
122
|
-
import { PostgresStore } from '
|
|
118
|
+
import { PostgresStore } from 'ace-auth/adapters';
|
|
123
119
|
// Requires 'pg' pool
|
|
124
120
|
const store = new PostgresStore(pool, 'auth_sessions_table');
|
|
125
121
|
```
|
|
@@ -129,7 +125,7 @@ const store = new PostgresStore(pool, 'auth_sessions_table');
|
|
|
129
125
|
Stores sessions as documents. Good for no-setup environments.
|
|
130
126
|
|
|
131
127
|
```typescript
|
|
132
|
-
import { MongoStore } from '
|
|
128
|
+
import { MongoStore } from 'ace-auth/adapters';
|
|
133
129
|
// Requires 'mongoose' connection
|
|
134
130
|
const store = new MongoStore(mongoose.connection.collection('sessions'));
|
|
135
131
|
```
|
|
@@ -145,7 +141,6 @@ Allow users to see all their logged-in devices and remotely log them out (like N
|
|
|
145
141
|
```typescript
|
|
146
142
|
// GET /api/devices
|
|
147
143
|
app.get('/api/devices', gatekeeper(auth), async (req, res) => {
|
|
148
|
-
// Returns: [{ device: { ip: '...', userAgent: 'Chrome' }, loginAt: '...' }]
|
|
149
144
|
const sessions = await auth.getActiveSessions(req.user.id);
|
|
150
145
|
res.json(sessions);
|
|
151
146
|
});
|
|
@@ -157,8 +152,6 @@ app.post('/api/devices/logout-all', gatekeeper(auth), async (req, res) => {
|
|
|
157
152
|
});
|
|
158
153
|
```
|
|
159
154
|
|
|
160
|
-
---
|
|
161
|
-
|
|
162
155
|
### 📧 Passwordless Login (OTP)
|
|
163
156
|
|
|
164
157
|
Built-in support for generating and verifying Email One-Time-Passwords.
|
|
@@ -187,12 +180,12 @@ app.post('/auth/verify-code', async (req, res) => {
|
|
|
187
180
|
|
|
188
181
|
## 🏗️ Architecture: "Graceful Expiration"
|
|
189
182
|
|
|
190
|
-
This is the core problem
|
|
183
|
+
This is the core problem AceAuth solves.
|
|
191
184
|
|
|
192
185
|
**Scenario:** User leaves a tab open for 20 minutes. The 15-minute JWT expires.
|
|
193
186
|
|
|
194
187
|
- **Standard Library:** Request fails (401). User is forced to log in again. 😡
|
|
195
|
-
- **
|
|
188
|
+
- **AceAuth:** Middleware catches the expiry error, checks the database, and issues a new token if the session is still valid.
|
|
196
189
|
|
|
197
190
|
```mermaid
|
|
198
191
|
sequenceDiagram
|
|
@@ -218,8 +211,12 @@ sequenceDiagram
|
|
|
218
211
|
|
|
219
212
|
This library is 100% covered by tests using Vitest.
|
|
220
213
|
|
|
221
|
-
- ✅ **Replay Protection:** OTPs are deleted immediately after use.
|
|
222
|
-
- ✅ **Tamper Proofing:** Tokens signed with invalid secrets are rejected immediately.
|
|
214
|
+
- ✅ **Replay Protection:** OTPs are deleted immediately after use.
|
|
215
|
+
- ✅ **Tamper Proofing:** Tokens signed with invalid secrets are rejected immediately.
|
|
223
216
|
- ✅ **Lazy Cleanup:** Expired sessions are automatically cleaned up from the user index during read operations to prevent memory leaks.
|
|
224
217
|
|
|
225
|
-
---
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## 📄 License
|
|
221
|
+
|
|
222
|
+
MIT
|