not-node 5.1.45 → 6.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.
@@ -0,0 +1,255 @@
1
+ const { error, log } = require("not-log")(module, "Identity//Token");
2
+ const { notRequestError } = require("not-error");
3
+ const CONST = require("../../auth/const");
4
+ const ROLES = require("../../auth/roles");
5
+ const { objHas } = require("../../common");
6
+ const phrase = require("not-locale").modulePhrase("not-node");
7
+
8
+ const JWT = require("jsonwebtoken");
9
+
10
+ module.exports = class IdentityProviderToken {
11
+ #tokenContent = null;
12
+ #token = null;
13
+
14
+ static #options = {};
15
+
16
+ static setOptions(options = {}) {
17
+ this.#options = options;
18
+ }
19
+
20
+ static #getOptions() {
21
+ return this.#options;
22
+ }
23
+
24
+ constructor(req) {
25
+ this.req = req;
26
+ return this;
27
+ }
28
+
29
+ static getTokenFromRequest(req) {
30
+ const auth = req.get("Authorization");
31
+ if (auth && auth.length) {
32
+ const [, token] = auth.split(" ");
33
+ return token;
34
+ }
35
+ return null;
36
+ }
37
+
38
+ #extractToken(req) {
39
+ const token = this.getTokenFromRequest(req);
40
+ if (token) {
41
+ this.#token = token;
42
+ }
43
+ }
44
+
45
+ #updateToken() {
46
+ this.#token = this.#encodeTokenContent();
47
+ return this.#token;
48
+ }
49
+
50
+ #decodeTokenContent() {
51
+ try {
52
+ if (this.#token) {
53
+ const secret = this.#getOptions().secret;
54
+ JWT.verify(this.#token, secret);
55
+ return JWT.decode(this.#token, secret);
56
+ }
57
+ return null;
58
+ } catch (e) {
59
+ error(e.message);
60
+ return null;
61
+ }
62
+ }
63
+
64
+ #encodeTokenContent() {
65
+ try {
66
+ if (this.#token) {
67
+ const secret = this.#getOptions().secret;
68
+ return JWT.sign(this.#tokenContent, secret);
69
+ }
70
+ return null;
71
+ } catch (e) {
72
+ error(e.message);
73
+ return null;
74
+ }
75
+ }
76
+
77
+ #extractTokenContent(req) {
78
+ this.#tokenContent = this.#decodeTokenContent(req);
79
+ }
80
+
81
+ get tokenContent() {
82
+ return this.#tokenContent;
83
+ }
84
+
85
+ get token() {
86
+ return this.#token;
87
+ }
88
+
89
+ static #validateSecretForToken({ secret, context }) {
90
+ if (
91
+ !secret ||
92
+ typeof secret === "undefined" ||
93
+ secret === null ||
94
+ secret === ""
95
+ ) {
96
+ throw new notRequestError(phrase("user_token_secret_not_valid"), {
97
+ ...context,
98
+ code: 500,
99
+ });
100
+ }
101
+ }
102
+
103
+ static #validateTTLForToken(tokenTTL) {
104
+ if (tokenTTL <= 0 || isNaN(tokenTTL)) {
105
+ log(phrase("user_token_ttl_not_set"));
106
+ tokenTTL = CONST.TOKEN_TTL;
107
+ }
108
+ return tokenTTL;
109
+ }
110
+
111
+ static #composeUserTokenPayload({ user, additionalFields = [] }) {
112
+ const addons = {};
113
+ if (Array.isArray(additionalFields)) {
114
+ additionalFields.forEach((fieldName) => {
115
+ if (objHas(user, fieldName)) {
116
+ addons[fieldName] = user[fieldName];
117
+ }
118
+ });
119
+ }
120
+ return {
121
+ _id: user._id,
122
+ role: user.role,
123
+ active: user.active,
124
+ username: user.username,
125
+ ...addons,
126
+ };
127
+ }
128
+
129
+ static #composeGuestTokenPayload() {
130
+ return {
131
+ _id: false,
132
+ role: CONST.DEFAULT_USER_ROLE_FOR_GUEST,
133
+ active: true,
134
+ username: phrase("user_role_guest"),
135
+ };
136
+ }
137
+
138
+ static createToken({
139
+ ip,
140
+ user,
141
+ additionalFields = ["emailConfirmed", "telephoneConfirmed"],
142
+ }) {
143
+ const context = { ip };
144
+ const secret = this.#getOptions().secret;
145
+ this.#validateSecretForToken({ secret, context });
146
+ let payload = {};
147
+ if (user) {
148
+ payload = this.#composeUserTokenPayload({ user, additionalFields });
149
+ } else {
150
+ payload = this.#composeGuestTokenPayload();
151
+ }
152
+ this.#setTokenExpiration(payload);
153
+ return JWT.sign(payload, secret);
154
+ }
155
+
156
+ static #setTokenExpiration(payload) {
157
+ const tokenTTL = this.#validateTTLForToken(this.#getOptions().ttl);
158
+ if (!objHas(payload, "exp")) {
159
+ payload.exp = Date.now() / 1000 + tokenTTL;
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Checks if user is authenticated
165
+ * @return {boolean} true - authenticated, false - guest
166
+ **/
167
+ isUser() {
168
+ return !!this.tokenContent?._id;
169
+ }
170
+
171
+ /**
172
+ * Returns user role from token object
173
+ * @return user role
174
+ **/
175
+ getRole() {
176
+ return this.tokenContent?.role ?? CONST.DEFAULT_USER_ROLE_FOR_GUEST;
177
+ }
178
+
179
+ /**
180
+ * Set user role for active session
181
+ * @param {Array<string>} role array of roles
182
+ **/
183
+ setRole(role) {
184
+ if (this.tokenContent) {
185
+ this.#tokenContent.role = [...role];
186
+ this.#updateToken();
187
+ }
188
+ return this;
189
+ }
190
+
191
+ /**
192
+ * Set user id for active session
193
+ * @param {string} _id user id
194
+ **/
195
+ setUserId(_id) {
196
+ if (this.tokenContent) {
197
+ this.#tokenContent._id = _id;
198
+ this.#updateToken();
199
+ }
200
+ return this;
201
+ }
202
+
203
+ isRoot() {
204
+ return (
205
+ this.isUser() &&
206
+ ROLES.compareRoles(
207
+ this.getRole(),
208
+ CONST.DEFAULT_USER_ROLE_FOR_ADMIN
209
+ )
210
+ );
211
+ }
212
+
213
+ /**
214
+ * Get user id for active session
215
+ **/
216
+ getUserId() {
217
+ return this.#tokenContent?._id;
218
+ }
219
+
220
+ /**
221
+ * returns token
222
+ **/
223
+ getSessionId() {
224
+ return this.token;
225
+ }
226
+
227
+ /**
228
+ * Set auth data in session, user id and role
229
+ * @param {string} id user id
230
+ * @param {string} role user role
231
+ **/
232
+ setAuth(id, role) {
233
+ this.setUserId(id);
234
+ this.setRole(role);
235
+ }
236
+
237
+ /**
238
+ * Set auth data in token to Guest
239
+ **/
240
+ setGuest() {
241
+ this.setAuth(null, [CONST.DEFAULT_USER_ROLE_FOR_GUEST]);
242
+ }
243
+
244
+ /**
245
+ * Reset session
246
+ * @param {object} req Express Request
247
+ **/
248
+ cleanse() {
249
+ this.setGuest();
250
+ }
251
+
252
+ static test(req) {
253
+ return !!this.getTokenFromRequest(req);
254
+ }
255
+ };
@@ -3,6 +3,7 @@ const CONST_AFTER_ACTION = "after";
3
3
 
4
4
  const obsoleteWarning = require("../obsolete");
5
5
 
6
+ const notAppIdentity = require("../identity");
6
7
  const Auth = require("../auth"),
7
8
  HttpError = require("../error").Http;
8
9
 
@@ -69,7 +70,7 @@ class notRoute {
69
70
  * @return {object} rule or null
70
71
  */
71
72
  selectRule(req) {
72
- const user = Auth.extractAuthData(req);
73
+ const user = notAppIdentity.extractAuthData(req);
73
74
  if (this.actionData) {
74
75
  return notRoute.actionAvailableByRule(this.actionData, user);
75
76
  }
package/static2.js ADDED
@@ -0,0 +1,24 @@
1
+ class Parent {
2
+ static getOptions() {
3
+ return this.#options;
4
+ }
5
+
6
+ static setOptions(opts) {
7
+ this.#options = opts;
8
+ }
9
+ }
10
+
11
+ class Child extends Parent {
12
+ static #options = {};
13
+ constructor() {
14
+ super();
15
+ }
16
+
17
+ run() {
18
+ Child.getOptions();
19
+ }
20
+ }
21
+
22
+ Parent.setOptions({ 1: "1" });
23
+
24
+ console.log(new Child().run());
File without changes
@@ -3,7 +3,7 @@ const {
3
3
  HttpExceptionForbidden,
4
4
  } = require("../../src/exceptions/http");
5
5
 
6
- module.exports = ({ Auth, HttpError, expect }) => {
6
+ module.exports = ({ Auth, expect }) => {
7
7
  describe("Routes", () => {
8
8
  describe("getIP", () => {
9
9
  it("req.header[x-forwarded-for]", () => {
package/test/auth.js CHANGED
@@ -265,20 +265,6 @@ describe("Auth", function () {
265
265
  expect(resultFunction).to.throw();
266
266
  });
267
267
 
268
- it("Both undefined, order defined Array with wrong types of element", function () {
269
- let resultFunction = () => {
270
- auth.checkSupremacy("undefined", "undefined", [12]);
271
- };
272
- expect(resultFunction).to.throw();
273
- });
274
-
275
- it("Both undefined, order defined Array with wrong types of element", function () {
276
- let resultFunction = () => {
277
- auth.checkSupremacy("undefined", "undefined", [null]);
278
- };
279
- expect(resultFunction).to.throw();
280
- });
281
-
282
268
  it("Both undefined, order defined Array with wrong types of element", function () {
283
269
  let resultFunction = () => {
284
270
  auth.checkSupremacy("undefined", "undefined", [null]);
@@ -437,7 +423,6 @@ describe("Auth", function () {
437
423
  require("./auth/routes.js")({ Auth: auth, HttpError, expect });
438
424
  require("./auth/roles.js")({ Auth: auth, HttpError, expect });
439
425
  require("./auth/rules.js")({ Auth: auth, HttpError, expect });
440
- require("./auth/session.js")({ Auth: auth, HttpError, expect });
441
426
  require("./auth/obsolete.js")({ Auth: auth, HttpError, expect });
442
427
  require("./auth/fields.js")({ Auth: auth, HttpError, expect });
443
428
  });
package/test/env.js CHANGED
@@ -1,24 +1,24 @@
1
- const expect = require('chai').expect,
2
- Env = require('../src/env');
1
+ const expect = require("chai").expect,
2
+ Env = require("../src/env");
3
3
 
4
- describe('Env', function() {
5
- describe('getEnv', function() {
6
- it('key exists', function() {
7
- const res = Env.getEnv('process');
8
- expect(res).to.be.equal('development');
9
- });
4
+ describe("Env", function () {
5
+ describe("getEnv", function () {
6
+ it("key exists", function () {
7
+ const res = Env.getEnv("process");
8
+ expect(res).to.be.equal("development");
9
+ });
10
10
 
11
- it('key not exists', function() {
12
- const res = Env.getEnv('key' + Math.random().toString());
13
- expect(res).to.be.undefined;
14
- });
15
- });
11
+ it("key not exists", function () {
12
+ const res = Env.getEnv("key" + Math.random().toString());
13
+ expect(res).to.be.undefined;
14
+ });
15
+ });
16
16
 
17
- describe('setEnv', function() {
18
- it('set', function() {
19
- const res = Env.setEnv('key', 'happy');
20
- expect(res).to.be.deep.equal(Env);
21
- expect(res.getEnv('key')).to.be.deep.equal('happy');
22
- });
23
- });
17
+ describe("setEnv", function () {
18
+ it("set", function () {
19
+ const res = Env.setEnv("key", "happy");
20
+ expect(res).to.be.deep.equal(Env);
21
+ expect(res.getEnv("key")).to.be.deep.equal("happy");
22
+ });
23
+ });
24
24
  });
@@ -0,0 +1 @@
1
+ module.exports = () => {};
@@ -0,0 +1,12 @@
1
+ module.exports = ({ expect }) => {
2
+ describe("notAppIdentity", () => {});
3
+
4
+ require("./identity.js")({ expect });
5
+
6
+ require("./providers/session.js")({
7
+ expect,
8
+ });
9
+ require("./providers/token.js")({
10
+ expect,
11
+ });
12
+ };
@@ -0,0 +1,227 @@
1
+ const Provider = require("../../../src/identity/providers/session");
2
+
3
+ const mongoose = require("mongoose");
4
+
5
+ const SESSION_NOT_EXISTS = "session not exists";
6
+
7
+ module.exports = ({ expect }) => {
8
+ describe(`${Provider.constructor.name}`, () => {
9
+ describe("isUser", function () {
10
+ it("check if user exists - true", function () {
11
+ var t = {
12
+ session: {
13
+ user: true,
14
+ },
15
+ };
16
+ var res = new Provider(t).isUser();
17
+ expect(res).to.eql(true);
18
+ });
19
+ it("check if user exists - false", function () {
20
+ var t = {
21
+ session: {},
22
+ };
23
+ var res = new Provider(t).isUser();
24
+ expect(res).to.eql(false);
25
+ });
26
+ });
27
+
28
+ describe("isRoot", function () {
29
+ it("check if user admin - true", function () {
30
+ var t = {
31
+ session: {
32
+ user: mongoose.Types.ObjectId(),
33
+ role: "root",
34
+ },
35
+ };
36
+ var res = new Provider(t).isRoot();
37
+ expect(res).to.eql(true);
38
+ });
39
+ it("check if user admin - false", function () {
40
+ var t = {
41
+ session: {
42
+ user: mongoose.Types.ObjectId(),
43
+ },
44
+ };
45
+ var res = new Provider(t).isRoot();
46
+ expect(res).to.eql(false);
47
+ });
48
+ });
49
+
50
+ describe("getRole", function () {
51
+ it("get role - root", function () {
52
+ var t = {
53
+ session: {
54
+ user: mongoose.Types.ObjectId(),
55
+ role: "root",
56
+ },
57
+ };
58
+ var res = new Provider(t).getRole();
59
+ expect(res).to.eql("root");
60
+ });
61
+ it("get role - undefined", function () {
62
+ var t = {
63
+ session: {
64
+ user: mongoose.Types.ObjectId(),
65
+ },
66
+ };
67
+ var res = new Provider(t).getRole();
68
+ expect(res).to.eql(undefined);
69
+ });
70
+ });
71
+
72
+ describe("setRole", function () {
73
+ it("session exist, set role - root", function () {
74
+ var t = {
75
+ session: {
76
+ user: mongoose.Types.ObjectId(),
77
+ role: "user",
78
+ },
79
+ };
80
+ new Provider(t).setRole("root");
81
+ expect(t.session.role).to.eql("root");
82
+ });
83
+
84
+ it("session not exist, set role - admin", function () {
85
+ var t = {};
86
+ new Provider(t).setRole("admin");
87
+ expect(t).to.be.deep.eql({});
88
+ });
89
+ });
90
+
91
+ describe("setUserId", function () {
92
+ it("session exist, set _id", function () {
93
+ const t = {
94
+ session: {
95
+ role: "user",
96
+ },
97
+ };
98
+ const id = mongoose.Types.ObjectId();
99
+ new Provider(t).setUserId(id);
100
+ expect(t.session.user).to.eql(id);
101
+ });
102
+
103
+ it("session not exist, set _id", function () {
104
+ const t = {};
105
+ const id = mongoose.Types.ObjectId();
106
+ new Provider(t).setUserId(id);
107
+ expect(t).to.be.deep.eql({});
108
+ });
109
+ });
110
+
111
+ describe("getUserId", function () {
112
+ it("session exist, user id exist", function () {
113
+ const t = {
114
+ session: {
115
+ user: mongoose.Types.ObjectId(),
116
+ role: "user",
117
+ },
118
+ };
119
+ const id = new Provider(t).getUserId();
120
+ expect(id.toString()).to.eql(t.session.user.toString());
121
+ });
122
+
123
+ it(SESSION_NOT_EXISTS, function () {
124
+ const t = {};
125
+ const id = new Provider(t).getUserId();
126
+ expect(id).to.be.deep.eql(undefined);
127
+ });
128
+ });
129
+
130
+ describe("getSessionId", function () {
131
+ it("session exist, session id exist", function () {
132
+ const t = {
133
+ session: {
134
+ id: mongoose.Types.ObjectId(),
135
+ role: "user",
136
+ },
137
+ };
138
+ const id = new Provider(t).getSessionId();
139
+ expect(id.toString()).to.eql(t.session.id.toString());
140
+ });
141
+
142
+ it(SESSION_NOT_EXISTS, function () {
143
+ const t = {};
144
+ const id = new Provider(t).getSessionId();
145
+ expect(id).to.be.deep.eql(undefined);
146
+ });
147
+ });
148
+
149
+ describe("setAuth", function () {
150
+ it("session exist", function () {
151
+ const t = {
152
+ session: {},
153
+ };
154
+ const id = mongoose.Types.ObjectId();
155
+ new Provider(t).setAuth(id, "root");
156
+ expect(t.session.user.toString()).to.eql(id.toString());
157
+ expect(t.session.role).to.eql("root");
158
+ });
159
+
160
+ it(SESSION_NOT_EXISTS, function () {
161
+ const t = {};
162
+ const id = mongoose.Types.ObjectId();
163
+ new Provider(t).setAuth(id, "user");
164
+ expect(t).to.be.deep.eql({});
165
+ });
166
+ });
167
+
168
+ describe("setGuest", function () {
169
+ it("session exist", function () {
170
+ const id = mongoose.Types.ObjectId();
171
+ const t = {
172
+ session: { user: id, role: "admin" },
173
+ user: { _id: id },
174
+ };
175
+ new Provider(t).setGuest();
176
+ expect(t.session.user).to.eql(null);
177
+ expect(t.user).to.eql(null);
178
+ expect(t.session.role).to.eql(["guest"]);
179
+ });
180
+
181
+ it(SESSION_NOT_EXISTS, function () {
182
+ const t = {};
183
+ new Provider(t).setGuest();
184
+ expect(t).to.be.deep.eql({});
185
+ });
186
+ });
187
+
188
+ describe("cleanse", function () {
189
+ it("session exist, destroy method exists", function () {
190
+ const id = mongoose.Types.ObjectId();
191
+ let destroyed = false;
192
+ const t = {
193
+ session: {
194
+ user: id,
195
+ role: "admin",
196
+ destroy() {
197
+ destroyed = true;
198
+ },
199
+ },
200
+ };
201
+ new Provider(t).cleanse();
202
+ expect(t.session.user).to.eql(null);
203
+ expect(t.session.role).to.eql(["guest"]);
204
+ expect(destroyed).to.eql(true);
205
+ });
206
+
207
+ it("session exist, destroy method exists", function () {
208
+ const id = mongoose.Types.ObjectId();
209
+ const t = {
210
+ session: {
211
+ user: id,
212
+ role: "admin",
213
+ },
214
+ };
215
+ new Provider(t).cleanse();
216
+ expect(t.session.user).to.eql(null);
217
+ expect(t.session.role).to.eql(["guest"]);
218
+ });
219
+
220
+ it(SESSION_NOT_EXISTS, function () {
221
+ const t = {};
222
+ new Provider(t).cleanse();
223
+ expect(t).to.be.deep.eql({});
224
+ });
225
+ });
226
+ });
227
+ };