@cocreate/authenticate 1.12.1 → 1.12.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.
@@ -3,7 +3,7 @@ name: Automated Workflow
3
3
  on:
4
4
  push:
5
5
  branches:
6
- - master
6
+ - main
7
7
 
8
8
  jobs:
9
9
  about:
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [1.12.2](https://github.com/CoCreate-app/CoCreate-authenticate/compare/v1.12.1...v1.12.2) (2026-07-19)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * set default branch to main ([4fcc1e9](https://github.com/CoCreate-app/CoCreate-authenticate/commit/4fcc1e9ebaf17e97641d6c44ea7c99dec96e3c63))
7
+
1
8
  ## [1.12.1](https://github.com/CoCreate-app/CoCreate-authenticate/compare/v1.12.0...v1.12.1) (2026-07-17)
2
9
 
3
10
 
package/README.md CHANGED
@@ -1,83 +1,135 @@
1
- # CoCreate-authenticate
1
+ # @cocreate/authentication
2
2
 
3
- A convenient chain handler allows user to chain multiple CoCreate components together. When one authenticate is complete next one will start. The sequence goes untill all authenticates completed. Grounded on Vanilla javascript, easily configured using HTML5 data-attributes and/or JavaScript API. Take it for a spin in our [playground!](https://cocreate.app/docs/authenticate)
3
+ A high-performance, native RS256 JWT session management and authentication engine. Designed as a zero-dependency ESM singleton cache layer, this engine dynamically provisions 2048-bit RSA keypairs, signs non-opaque session tokens, syncs live connection statuses back to databases via CoCreate CRUD gateways, and runs fast local public-key signature verification to guard distributed nodes against forged requests.
4
4
 
5
- ![GitHub latest release](https://img.shields.io/github/v/release/CoCreate-app/CoCreate-authenticate?style=flat-square)
6
- ![GitHub contributors](https://img.shields.io/github/contributors/CoCreate-app/CoCreate-authenticate?style=flat-square)
7
- ![License](https://img.shields.io/static/v1?style=flat-square&label=license&message=SSPL&color=green)
8
- ![Hiring](https://img.shields.io/static/v1?style=flat-square&label=&message=Hiring&color=blueviolet)
5
+ ---
9
6
 
10
- ![CoCreate-authenticate](https://cdn.cocreate.app/docs/CoCreate-authenticate.gif)
7
+ ## Table of Contents
11
8
 
12
- ## [Docs & Demo](https://cocreate.app/docs/authenticate)
9
+ * [Features](#features)
10
+ * [Installation](#installation)
11
+ * [Usage](#usage)
12
+ * [How it Works](#how-it-works)
13
+ * [API Reference](#api-reference)
14
+ * [How to Contribute](#how-to-contribute)
15
+ * [License](#license)
13
16
 
14
- For a complete guide and working demo refer to the [doumentation](https://cocreate.app/docs/authenticate)
17
+ ---
15
18
 
16
- ## CDN
19
+ ## Features
17
20
 
18
- ```html
19
- <script src="https://cdn.cocreate.app/authenticate/latest/CoCreate-authenticate.min.js"></script>
20
- ```
21
+ * **Zero-Dependency Native RS256:** Leverages Node's internal `node:crypto` subsystem to sign and verify JSON Web Tokens (JWT) using asymmetric cryptography without relying on massive external dependencies.
22
+ * **Ephemeral Key-Pair Lifecycles:** Automatically provisions 2048-bit RSA key pairs, assigns isolated tracker IDs (`kid`), and handles local cache purging when lifetimes expire.
23
+ * **Multi-Layered Hot Cache:** Accelerates performance by keeping active key pairs and client connections within rapid-access memory structures (`Map`), dropping signature evaluation latency to a minimum.
24
+ * **CRUD Gateway Synchronization:** Seamlessly broadcasts active user sessions and lifecycle states down to persistent target database collections via internal protocol events (`object.update`).
25
+ * **Fast Signature Guard:** Isolates signature validations from state persistence layers, checking incoming signatures against active in-memory keys to drop structural forgery attempts instantly before making database round trips.
21
26
 
22
- ```html
23
- <script src="https://cdn.cocreate.app/authenticate/latest/CoCreate-authenticate.min.css"></script>
24
- ```
27
+ ---
25
28
 
26
- ## NPM
29
+ ## Installation
30
+
31
+ ```bash
32
+ npm install @cocreate/authentication
27
33
 
28
- ```shell
29
- $ npm i @cocreate/authenticate
30
34
  ```
31
35
 
32
- # Table of Contents
36
+ ---
33
37
 
34
- - [Table of Contents](#table-of-contents)
35
- - [Announcements](#announcements)
36
- - [Roadmap](#roadmap)
37
- - [How to Contribute](#how-to-contribute)
38
- - [About](#about)
39
- - [License](#license)
38
+ ## Usage
40
39
 
41
- <a name="announcements"></a>
40
+ ### Token Issuance (Session Generation)
42
41
 
43
- # Announcements
42
+ Generate a cryptographically signed RS256 token for a successful client connection and synchronize the state into database layers:
44
43
 
45
- All updates to this library are documented in our [CHANGELOG](https://github.com/CoCreate-app/CoCreate-authenticate/blob/master/CHANGELOG.md) and [releases](https://github.com/CoCreate-app/CoCreate-authenticate/releases). You may also subscribe to email for releases and breaking changes.
44
+ ```javascript
45
+ import auth from '@cocreate/authentication';
46
46
 
47
- <a name="roadmap"></a>
47
+ const sessionParams = {
48
+ organization_id: "64b9a32e18f21bc56789abcd",
49
+ user_id: "64b9a35f18f21bc5e9812456",
50
+ clientId: "client_ws_90210_alpha",
51
+ host: "app.cocreate.js"
52
+ };
48
53
 
49
- # Roadmap
54
+ // Creates/reuses keys, signs the JWT, and saves the session
55
+ const token = auth.encodeToken(
56
+ sessionParams.organization_id,
57
+ sessionParams.user_id,
58
+ sessionParams.clientId,
59
+ sessionParams.host
60
+ );
50
61
 
51
- If you are interested in the future direction of this project, please take a look at our open [issues](https://github.com/CoCreate-app/CoCreate-authenticate/issues) and [pull requests](https://github.com/CoCreate-app/CoCreate-authenticate/pulls). We would love to hear your feedback.
62
+ console.log("Generated JWT:", token);
52
63
 
53
- <a name="about"></a>
64
+ ```
54
65
 
55
- # About
66
+ ### Token Verification & Decoding
56
67
 
57
- CoCreate-authenticate is guided and supported by the CoCreate Developer Experience Team.
68
+ Intercept incoming request channels, extract identity records, and catch forged signatures locally:
58
69
 
59
- Please Email the Developer Experience Team [here](mailto:develop@cocreate.app) in case of any queries.
70
+ ```javascript
71
+ import auth from '@cocreate/authentication';
60
72
 
61
- CoCreate-authenticate is maintained and funded by CoCreate. The names and logos for CoCreate are trademarks of CoCreate, LLC.
73
+ const inboundToken = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6...";
74
+ const context = {
75
+ organization_id: "64b9a32e18f21bc56789abcd",
76
+ clientId: "client_ws_90210_alpha",
77
+ host: "app.cocreate.js"
78
+ };
62
79
 
63
- <a name="contribute"></a>
80
+ // Verifies integrity against local keys and falls back to structural DB records if required
81
+ const session = await auth.decodeToken(
82
+ inboundToken,
83
+ context.organization_id,
84
+ context.clientId,
85
+ context.host
86
+ );
64
87
 
65
- # How to Contribute
88
+ if (!session.user_id) {
89
+ console.log("Authentication Failed: Session missing, expired, or signature forged.");
90
+ } else {
91
+ console.log(`Authenticated User: ${session.user_id}, Expires at: ${session.expires}`);
92
+ }
66
93
 
67
- We encourage contribution to our libraries (you might even score some nifty swag), please see our [CONTRIBUTING](https://github.com/CoCreate-app/CoCreate-authenticate/blob/master/CONTRIBUTING.md) guide for details.
94
+ ```
68
95
 
69
- We want this library to be community-driven, and CoCreate led. We need your help to realize this goal. To help make sure we are building the right things in the right order, we ask that you create [issues](https://github.com/CoCreate-app/CoCreate-authenticate/issues) and [pull requests](https://github.com/CoCreate-app/CoCreate-authenticate/pulls) or merely upvote or comment on existing issues or pull requests.
96
+ ---
70
97
 
71
- We appreciate your continued support, thank you!
98
+ ## How it Works
72
99
 
73
- <a name="license"></a>
100
+ 1. **Lifecycle Rotation & Key Selection:** When `encodeToken` runs, the engine checks its active in-memory cache map. It automatically prunes expired keys and searches for a valid, unexpired asymmetric pair. If none are found, it triggers a 2048-bit RSA generation run.
101
+ 2. **Asymmetric Envelope Signing:** It constructs standard JSON Web Token blocks (Header with `kid` + Payload with `user_id` and timestamps), serializes them into Base64URL string footprints, and signs the unified buffer natively via an asymmetric SHA-256 algorithm.
102
+ 3. **Persisted State Bridging:** Once the token is assembled, the engine logs the structure into local memory slots and issues asynchronous events (`object.update`) down to central arrays to keep database records aligned with client connection parameters.
103
+ 4. **Signature Pre-Screening:** During decoding checks (`decodeToken`), the engine parses the incoming header instantly to read the key identification string (`kid`). If that key is cached locally, it executes an direct crypto check (`verifySignature`). Forged payloads are intercepted and dropped right here, skipping down-stream infrastructure operations.
104
+ 5. **State Invalidation & Synchronization:** If local signatures check out but matching memory records are absent (e.g., when scaled out across distributed processes), it sends query lookups down to persistent storage (`read`). If the token is verified to be expired or invalid, the engine clears all local tracking points and flags the database to nullify the state.
74
105
 
75
- # License
106
+ ---
76
107
 
77
- This software is dual-licensed under the GNU Affero General Public License version 3 (AGPLv3) and a commercial license.
108
+ ## API Reference
109
+
110
+ ### Default Manifest Exports
78
111
 
79
- - **Open Source Use**: For open-source projects and non-commercial use, this software is available under the AGPLv3. The AGPLv3 allows you to freely use, modify, and distribute this software, provided that all modifications and derivative works are also licensed under the AGPLv3. For the full license text, see the [LICENSE file](https://github.com/CoCreate-app/CoCreate-authenticate/blob/master/LICENSE).
112
+ | Method Selector | Payload Input Structure | Returns | Role |
113
+ | --- | --- | --- | --- |
114
+ | **`createKeyPair()`** | *None* | `Object` | Generates a new secure 2048-bit RSA key pair object with automatic expiration tracking. |
115
+ | **`deleteKeyPair(keyPair)`** | `keyPair: Object` | `Boolean` | Explicitly removes targeted cryptographic configurations from the local tracking cache. |
116
+ | **`encodeToken(orgId, userId, clientId, host)`** | `String, String, String, String` | `String` | Generates a zero-dependency RS256 token, assigns local session parameters, and pushes changes to databases. |
117
+ | **`decodeToken(token, orgId, clientId, host)`** | `String, String, String, String` | `Object` | Decodes signatures, catches structural forgery attempts instantly, and returns verified identity states. |
118
+ | **`read(orgId, clientId, host)`** | `String, String, String` | `Promise<Object|null>` | Reaches out into data backends via internal CRUD pathways to retrieve active persistent session payloads. |
80
119
 
81
- - **Commercial Use**: For-profit companies and individuals intending to use this software for commercial purposes must obtain a commercial license. The commercial license is available when you sign up for an API key on our [website](https://cocreate.app). This license permits proprietary use and modification of the software without the copyleft requirements of the AGPLv3. It is ideal for integrating this software into proprietary commercial products and applications.
120
+ ---
121
+
122
+ ## How to Contribute
123
+
124
+ We encourage contribution to our libraries (you might even score some nifty swag), please see our [CONTRIBUTING.md](https://github.com/CoCreate-app/CoCreate-authentication/blob/master/CONTRIBUTING.md) guide for details. If you encounter any bugs or wish to make feature requests, please submit an issue on our [GitHub Issues](https://github.com/CoCreate-app/CoCreate-authentication/issues) tracker. We want this library to be community-driven, and CoCreate led. We need your help to realize this goal.
125
+
126
+ For broader system configurations and API guides, please visit our [CoCreate Authentication Documentation](https://cocreatejs.com/docs/authentication).
127
+
128
+ ---
129
+
130
+ ## License
131
+
132
+ This software is dual-licensed under the GNU Affero General Public License version 3 (AGPLv3) and a commercial license.
82
133
 
83
- If you have not purchased a commercial license and intend to use this software for commercial purposes, you are required to sign up for an API key on our website.
134
+ * **Open Source Use:** For open-source projects and non-commercial use, this software is available under the AGPLv3. For the full license text, see the LICENSE file.
135
+ * **Commercial Use:** For-profit companies and individuals intending to use this software for commercial purposes must obtain a commercial license. The commercial license is available when you sign up for an API key on our website.
package/package.json CHANGED
@@ -1,16 +1,22 @@
1
1
  {
2
2
  "name": "@cocreate/authenticate",
3
- "version": "1.12.1",
4
- "description": "A simple authenticate component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.",
3
+ "version": "1.12.3",
4
+ "description": "A high-performance, zero-dependency ESM session management and authentication engine using native RS256 asymmetric cryptography, ephemeral 2048-bit RSA keypair rotation, and reactive database state synchronization.",
5
5
  "keywords": [
6
- "authenticate",
7
- "low-code",
8
- "realtime",
9
- "realtime-framework",
10
- "collaboration",
11
- "shared-editing",
12
- "html5-framework",
13
- "javascript-framework"
6
+ "cocreate",
7
+ "cocreate-app",
8
+ "authentication",
9
+ "auth",
10
+ "jwt",
11
+ "rs256",
12
+ "crypto",
13
+ "session-management",
14
+ "rsa-2048",
15
+ "multi-tenant",
16
+ "token-verification",
17
+ "zero-dependency",
18
+ "esm",
19
+ "security"
14
20
  ],
15
21
  "scripts": {
16
22
  "start": "webpack --config webpack.config.js --watch",
@@ -30,8 +36,5 @@
30
36
  },
31
37
  "type": "module",
32
38
  "main": "./src/index.js",
33
- "homepage": "https://cocreate.app/docs/authenticate",
34
- "dependencies": {
35
- "jsonwebtoken": "^9.0.0"
36
- }
39
+ "homepage": "https://cocreate.app/docs/authenticate"
37
40
  }
package/release.config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  dryRun: false,
3
- branches: ["master"],
3
+ branches: ["main"],
4
4
  plugins: [
5
5
  "@semantic-release/commit-analyzer",
6
6
  "@semantic-release/release-notes-generator",
package/src/index.js CHANGED
@@ -20,29 +20,34 @@
20
20
  // you must obtain a commercial license from CoCreate LLC.
21
21
  // For details, visit <https://cocreate.app/licenses/> or contact us at sales@cocreate.app.
22
22
 
23
- import crypto from 'crypto';
24
- import jwt from 'jsonwebtoken';
23
+ import crypto from 'node:crypto';
25
24
  import crud from '@cocreate/crud-server';
26
25
 
27
- // ==========================================
28
- // Module-Level Sandbox State (ESM Singleton Container)
29
- // ==========================================
30
26
  const tokenExpiration = 60; // Token expiration in minutes
31
- const keyPairs = new Map();
32
- const sessions = new Map();
27
+ const keyPairs = new Map(); // Active public/private cryptographic key pairs
28
+ const sessions = new Map(); // In-memory hot session storage cache
33
29
 
34
30
  /**
35
31
  * Generates a new RSA key pair dynamically and tracks its expiration lifecycle.
36
32
  * @returns {Object} Newly created key pair configuration
37
33
  */
38
34
  function createKeyPair() {
35
+ // Generate secure 2048-bit RSA keys natively using Node's built-in Crypto module
39
36
  const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
40
37
  modulusLength: 2048,
38
+ publicKeyEncoding: {
39
+ type: 'spki',
40
+ format: 'pem'
41
+ },
42
+ privateKeyEncoding: {
43
+ type: 'pkcs8',
44
+ format: 'pem'
45
+ }
41
46
  });
42
47
 
43
- const created = new Date(new Date().toISOString()).getTime();
48
+ const created = Date.now();
44
49
  const keyPair = {
45
- _id: crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2),
50
+ _id: crypto.randomUUID(),
46
51
  privateKey,
47
52
  publicKey,
48
53
  created,
@@ -53,6 +58,7 @@ function createKeyPair() {
53
58
  return keyPair;
54
59
  }
55
60
 
61
+
56
62
  /**
57
63
  * Deletes an expired or revoked RSA key pair from local tracking.
58
64
  * @param {Object} keyPair - The target key pair to remove
@@ -63,15 +69,35 @@ function deleteKeyPair(keyPair) {
63
69
  }
64
70
  }
65
71
 
72
+ /**
73
+ * Helper to encode JSON payloads safely as Base64URL string representations
74
+ */
75
+ function base64urlEncode(obj) {
76
+ return Buffer.from(JSON.stringify(obj)).toString('base64url');
77
+ }
78
+
79
+ /**
80
+ * Helper to decode Base64URL strings safely back to JSON objects
81
+ */
82
+ function base64urlDecode(str) {
83
+ try {
84
+ return JSON.parse(Buffer.from(str, 'base64url').toString('utf8'));
85
+ } catch {
86
+ return null;
87
+ }
88
+ }
89
+
90
+
66
91
  /**
67
92
  * Creates and signs a new token utilizing the latest available RSA key pair.
68
- * Saves session markers back to storage and registers client tracking nodes.
93
+ * Generates a zero-dependency RS256 JWT natively.
69
94
  */
70
95
  function encodeToken(organization_id, user_id, clientId, host) {
71
96
  let keyPair = null;
72
- const currentTime = new Date(new Date().toISOString()).getTime();
97
+ const currentTime = Date.now();
73
98
 
74
- for (let [key, value] of keyPairs) {
99
+ // Prune expired keypairs and locate/reuse a valid active one
100
+ for (const [key, value] of keyPairs) {
75
101
  if (currentTime > value.expires) {
76
102
  deleteKeyPair(value);
77
103
  } else {
@@ -83,10 +109,33 @@ function encodeToken(organization_id, user_id, clientId, host) {
83
109
  keyPair = createKeyPair();
84
110
  }
85
111
 
86
- const token = jwt.sign({ user_id, clientId }, keyPair.privateKey, {
87
- algorithm: 'RS256',
88
- expiresIn: tokenExpiration * 60
89
- });
112
+ const iat = Math.floor(currentTime / 1000);
113
+ const exp = iat + (tokenExpiration * 60);
114
+
115
+ // Standard JWT Segments (Header containing Key ID + Alg, and standard Payload)
116
+ const header = {
117
+ alg: 'RS256',
118
+ typ: 'JWT',
119
+ kid: keyPair._id
120
+ };
121
+
122
+ const payload = {
123
+ user_id,
124
+ clientId,
125
+ iat,
126
+ exp
127
+ };
128
+
129
+ const encodedHeader = base64urlEncode(header);
130
+ const encodedPayload = base64urlEncode(payload);
131
+ const signatureInput = `${encodedHeader}.${encodedPayload}`;
132
+
133
+ // Cryptographically sign the envelope natively using SHA-256 and RSA Private Key
134
+ const signer = crypto.createSign('RSA-SHA256');
135
+ signer.update(signatureInput);
136
+ const signature = signer.sign(keyPair.privateKey, 'base64url');
137
+
138
+ const token = `${signatureInput}.${signature}`;
90
139
 
91
140
  const session = {
92
141
  user_id,
@@ -114,6 +163,7 @@ function encodeToken(organization_id, user_id, clientId, host) {
114
163
  return token;
115
164
  }
116
165
 
166
+
117
167
  /**
118
168
  * Reads, parses, and validates the configuration and active state of client sessions.
119
169
  */
@@ -137,13 +187,53 @@ async function read(organization_id, clientId, host) {
137
187
  return null;
138
188
  }
139
189
 
190
+
191
+ /**
192
+ * Verifies the integrity of a cryptographic token envelope natively.
193
+ */
194
+ function verifySignature(token, publicKey) {
195
+ try {
196
+ const parts = token.split('.');
197
+ if (parts.length !== 3) return false;
198
+
199
+ const [header, payload, signature] = parts;
200
+ const verifier = crypto.createVerify('RSA-SHA256');
201
+ verifier.update(`${header}.${payload}`);
202
+
203
+ return verifier.verify(publicKey, signature, 'base64url');
204
+ } catch {
205
+ return false;
206
+ }
207
+ }
208
+
140
209
  /**
141
210
  * Verifies and decodes an incoming session token, resolving the associated user identifier.
211
+ * Incorporates local RSA public-key validation before hitting session layers.
142
212
  */
143
213
  async function decodeToken(token, organization_id, clientId, host) {
144
214
  if (!token) return {};
145
215
 
146
- const currentTime = new Date().getTime();
216
+ const parts = token.split('.');
217
+ if (parts.length !== 3) return {};
218
+
219
+ const [headerB64, payloadB64, signatureB64] = parts;
220
+ const header = base64urlDecode(headerB64);
221
+ const payload = base64urlDecode(payloadB64);
222
+
223
+ if (!header || !payload) return {};
224
+
225
+ // 1. Core Security Check: Identify active signing keys using Key ID (kid)
226
+ const keyPair = keyPairs.get(header.kid);
227
+ if (keyPair) {
228
+ // Reject forged signatures instantly without proceeding to database/session checks
229
+ const isValid = verifySignature(token, keyPair.publicKey);
230
+ if (!isValid) {
231
+ console.warn(`[SECURITY WARNING] Blocked forged token attempt on clientId: ${clientId}`);
232
+ return {};
233
+ }
234
+ }
235
+
236
+ const currentTime = Date.now();
147
237
  let session = sessions.get(clientId);
148
238
 
149
239
  if (!session || session.token !== token) {