@cocreate/authenticate 1.6.0 → 1.8.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/CHANGELOG.md +24 -0
- package/README.md +5 -14
- package/package.json +2 -3
- package/src/index.js +120 -106
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
# [1.8.0](https://github.com/CoCreate-app/CoCreate-authenticate/compare/v1.7.0...v1.8.0) (2023-12-05)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* removed "@cocreate/utlis" ([3726368](https://github.com/CoCreate-app/CoCreate-authenticate/commit/372636836f00c830c31baa6e85e138075ec510af))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* manage sessions using crud ([81a3d9b](https://github.com/CoCreate-app/CoCreate-authenticate/commit/81a3d9b15402b305f61ad23d6699e30277f1a0bd))
|
|
12
|
+
|
|
13
|
+
# [1.7.0](https://github.com/CoCreate-app/CoCreate-authenticate/compare/v1.6.0...v1.7.0) (2023-11-25)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* update licensing details ([3fa12ff](https://github.com/CoCreate-app/CoCreate-authenticate/commit/3fa12ffeafaf22ae1121c567d0ff735cc4b735a3))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* upgrade dependencies for latest features and fixes ([850fdc1](https://github.com/CoCreate-app/CoCreate-authenticate/commit/850fdc199c7288e2c95eadae5bda6a23d09fe192))
|
|
24
|
+
|
|
1
25
|
# [1.6.0](https://github.com/CoCreate-app/CoCreate-authenticate/compare/v1.5.0...v1.6.0) (2023-11-25)
|
|
2
26
|
|
|
3
27
|
|
package/README.md
CHANGED
|
@@ -72,21 +72,12 @@ We appreciate your continued support, thank you!
|
|
|
72
72
|
|
|
73
73
|
<a name="license"></a>
|
|
74
74
|
|
|
75
|
-
#
|
|
75
|
+
# License
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
This software is dual-licensed under the GNU Affero General Public License version 3 (AGPLv3) and a commercial license.
|
|
78
78
|
|
|
79
|
-
|
|
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).
|
|
80
80
|
|
|
81
|
-
|
|
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.
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
commercial use must purchase a commercial license. This license allows
|
|
85
|
-
source code modifications, but does not permit redistribution of
|
|
86
|
-
modifications.
|
|
87
|
-
|
|
88
|
-
The commercial license is designed for you to use CoCreate-authenticate in commercial
|
|
89
|
-
products and applications, without the provisions of the SSPL. With the
|
|
90
|
-
commercial license, your code is kept propietary, to yourself. If you
|
|
91
|
-
want to use CoCreate-authenticate to develop commercial sites, themes, projects, and
|
|
92
|
-
applications, the commercial license is the appropriate license.
|
|
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.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/authenticate",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "A simple authenticate component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"authenticate",
|
|
@@ -33,14 +33,13 @@
|
|
|
33
33
|
"type": "git",
|
|
34
34
|
"url": "git+https://github.com/CoCreate-app/CoCreate-authenticate.git"
|
|
35
35
|
},
|
|
36
|
-
"
|
|
36
|
+
"author": "CoCreate LLC",
|
|
37
37
|
"bugs": {
|
|
38
38
|
"url": "https://github.com/CoCreate-app/CoCreate-authenticate/issues"
|
|
39
39
|
},
|
|
40
40
|
"main": "./src/index.js",
|
|
41
41
|
"homepage": "https://cocreate.app/docs/authenticate",
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@cocreate/utils": "^1.28.0",
|
|
44
43
|
"jsonwebtoken": "^9.0.0"
|
|
45
44
|
}
|
|
46
45
|
}
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const crypto = require('crypto');
|
|
2
2
|
const jwt = require('jsonwebtoken');
|
|
3
|
-
const { ObjectId } = require('@cocreate/utils');
|
|
4
3
|
|
|
5
4
|
// Configuration
|
|
6
5
|
const tokenExpiration = 60; // Token expiration in minutes
|
|
@@ -8,124 +7,139 @@ const tokenExpiration = 60; // Token expiration in minutes
|
|
|
8
7
|
// Array to store key pairs
|
|
9
8
|
const keyPairs = new Map();
|
|
10
9
|
|
|
11
|
-
// Map to store authenticated user
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
// TODO: user can have multiple sessions
|
|
15
|
-
const activeSessions = new Map();
|
|
16
|
-
|
|
17
|
-
// crud.listen('object.create', function (data) {
|
|
18
|
-
// if (data.object && data.object[0] && data.object[0].type === 'keyPair')
|
|
19
|
-
// keyPairs.set(data.object[0]._id, data.object[0]);
|
|
20
|
-
// });
|
|
21
|
-
|
|
22
|
-
// crud.listen('object.delete', function (data) {
|
|
23
|
-
// if (data.object && data.object[0] && data.object[0].type === 'keyPair')
|
|
24
|
-
// keyPairs.delete(data.object[0]._id);
|
|
25
|
-
// });
|
|
26
|
-
|
|
27
|
-
// Create new RSA key pair
|
|
28
|
-
function createKeyPair() {
|
|
29
|
-
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
|
|
30
|
-
modulusLength: 2048,
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
let created = new Date(new Date().toISOString()).getTime()
|
|
34
|
-
const keyPair = {
|
|
35
|
-
_id: ObjectId().toString(),
|
|
36
|
-
privateKey,
|
|
37
|
-
publicKey,
|
|
38
|
-
created,
|
|
39
|
-
expires: created + tokenExpiration * 60 * 1000, // Convert minutes to milliseconds
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
keyPairs.set(keyPair._id, keyPair);
|
|
43
|
-
|
|
44
|
-
// crud.send({
|
|
45
|
-
// method: 'object.create',
|
|
46
|
-
// array: 'keys',
|
|
47
|
-
// object: {
|
|
48
|
-
// ...keyPair,
|
|
49
|
-
// },
|
|
50
|
-
// organization_id: process.env.organization_id,
|
|
51
|
-
// });
|
|
52
|
-
|
|
53
|
-
return keyPair;
|
|
54
|
-
}
|
|
10
|
+
// Map to store authenticated user payload and tokens
|
|
11
|
+
const sessions = new Map();
|
|
55
12
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
organization_id: process.env.organization_id,
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// Add retrieved key pairs to the keyPairs array
|
|
72
|
-
if (keys.object && keys.object.length) {
|
|
73
|
-
keys.object.forEach((keyPair) => {
|
|
74
|
-
keyPairs.set(keyPair._id, keyPair);
|
|
13
|
+
class CoCreateAuthenticate {
|
|
14
|
+
constructor(crud) {
|
|
15
|
+
this.wsManager = crud.wsManager
|
|
16
|
+
this.crud = crud
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Create new RSA key pair
|
|
20
|
+
createKeyPair() {
|
|
21
|
+
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
|
|
22
|
+
modulusLength: 2048,
|
|
75
23
|
});
|
|
24
|
+
|
|
25
|
+
let created = new Date(new Date().toISOString()).getTime()
|
|
26
|
+
const keyPair = {
|
|
27
|
+
privateKey,
|
|
28
|
+
publicKey,
|
|
29
|
+
created,
|
|
30
|
+
expires: created + tokenExpiration * 60 * 1000, // Convert minutes to milliseconds
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
keyPairs.set(keyPair._id, keyPair);
|
|
34
|
+
|
|
35
|
+
// crud.send({
|
|
36
|
+
// method: 'object.create',
|
|
37
|
+
// array: 'keys',
|
|
38
|
+
// object: {
|
|
39
|
+
// ...keyPair,
|
|
40
|
+
// },
|
|
41
|
+
// organization_id: process.env.organization_id,
|
|
42
|
+
// });
|
|
43
|
+
|
|
44
|
+
return keyPair;
|
|
76
45
|
}
|
|
77
|
-
}
|
|
78
46
|
|
|
79
|
-
// Delete new RSA key pair
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
47
|
+
// Delete new RSA key pair
|
|
48
|
+
deleteKeyPair(keyPair) {
|
|
49
|
+
keyPairs.delete(keyPair._id)
|
|
50
|
+
// crud.send({
|
|
51
|
+
// method: 'object.delete',
|
|
52
|
+
// array: 'keys',
|
|
53
|
+
// object: {
|
|
54
|
+
// _id: keyPair._id,
|
|
55
|
+
// type: 'RSA'
|
|
56
|
+
// },
|
|
57
|
+
// organization_id: process.env.organization_id,
|
|
58
|
+
// });
|
|
59
|
+
}
|
|
92
60
|
|
|
93
|
-
// Function to sign a new token using the newest keyPair
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
61
|
+
// Function to sign a new token using the newest keyPair
|
|
62
|
+
encodeToken(organization_id, user_id, clientId) {
|
|
63
|
+
let keyPair = null
|
|
64
|
+
const currentTime = new Date(new Date().toISOString()).getTime();
|
|
65
|
+
for (let [key, value] of keyPairs) {
|
|
66
|
+
if (currentTime > value.expires) {
|
|
67
|
+
this.deleteKeyPair(value);
|
|
68
|
+
} else {
|
|
69
|
+
keyPair = value
|
|
70
|
+
}
|
|
102
71
|
}
|
|
103
|
-
}
|
|
104
72
|
|
|
105
|
-
|
|
106
|
-
|
|
73
|
+
if (!keyPair) {
|
|
74
|
+
keyPair = this.createKeyPair();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const token = jwt.sign({ user_id, clientId }, keyPair.privateKey, { algorithm: 'RS256', expiresIn: tokenExpiration * 60 });
|
|
78
|
+
|
|
79
|
+
// TODO: session could have previous user ip and device information which we could use to comapre to current ip and device information
|
|
80
|
+
const session = { user_id, clientId, token, expires: currentTime + tokenExpiration * 60 * 1000 }
|
|
81
|
+
sessions.set(clientId, session)
|
|
82
|
+
|
|
83
|
+
this.crud.send({
|
|
84
|
+
method: 'object.update',
|
|
85
|
+
array: 'clients',
|
|
86
|
+
object: {
|
|
87
|
+
_id: clientId,
|
|
88
|
+
session,
|
|
89
|
+
},
|
|
90
|
+
upsert: true,
|
|
91
|
+
organization_id
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return token;
|
|
107
95
|
}
|
|
108
96
|
|
|
109
|
-
//
|
|
97
|
+
// Verify and decode a token using the available keys
|
|
98
|
+
async decodeToken(token, organization_id, clientId) {
|
|
99
|
+
if (!token)
|
|
100
|
+
return {}
|
|
101
|
+
const currentTime = new Date().getTime();
|
|
102
|
+
|
|
103
|
+
let session = sessions.get(clientId)
|
|
104
|
+
if (!session || session.token !== token)
|
|
105
|
+
session = await this.read(organization_id, clientId)
|
|
106
|
+
|
|
107
|
+
// TODO: request must be made from same clientId and user_id that created the token
|
|
108
|
+
if (session && currentTime < session.expires && session.token === token)
|
|
109
|
+
return { user_id: session.user_id, expires: session.expires };
|
|
110
|
+
|
|
111
|
+
sessions.delete(clientId)
|
|
112
|
+
this.crud.send({
|
|
113
|
+
method: 'object.update',
|
|
114
|
+
array: 'clients',
|
|
115
|
+
object: {
|
|
116
|
+
_id: clientId,
|
|
117
|
+
session: undefined
|
|
118
|
+
},
|
|
119
|
+
organization_id,
|
|
120
|
+
});
|
|
110
121
|
|
|
111
|
-
|
|
112
|
-
users.set(token, { _id: payload.user_id, expires: currentTime + tokenExpiration * 60 * 1000 })
|
|
113
|
-
return token;
|
|
114
|
-
}
|
|
122
|
+
return {}
|
|
115
123
|
|
|
116
|
-
|
|
117
|
-
function decodeToken(token) {
|
|
118
|
-
const currentTime = new Date().getTime();
|
|
124
|
+
}
|
|
119
125
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
126
|
+
async read(organization_id, clientId) {
|
|
127
|
+
const client = await this.crud.send({
|
|
128
|
+
method: 'object.read',
|
|
129
|
+
array: 'clients',
|
|
130
|
+
object: {
|
|
131
|
+
_id: clientId
|
|
132
|
+
},
|
|
133
|
+
organization_id,
|
|
134
|
+
});
|
|
123
135
|
|
|
124
|
-
|
|
125
|
-
|
|
136
|
+
if (client.object && client.object.length) {
|
|
137
|
+
sessions.set(clientId, client.object[0].session)
|
|
138
|
+
}
|
|
126
139
|
|
|
127
|
-
|
|
140
|
+
return client.object[0].session
|
|
141
|
+
}
|
|
128
142
|
|
|
129
|
-
|
|
143
|
+
}
|
|
130
144
|
|
|
131
|
-
module.exports =
|
|
145
|
+
module.exports = CoCreateAuthenticate;
|