not-node 5.1.45 → 6.0.1

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/index.js CHANGED
@@ -15,6 +15,10 @@ module.exports.Manifest = require("./src/manifest/manifest");
15
15
  module.exports.notManifestRouteResultFilter = require("./src/manifest/result.filter");
16
16
  /** Web Application */
17
17
  module.exports.notApp = require("./src/app");
18
+ /** Application User Identity */
19
+ module.exports.notAppIdentity = require("./src/identity");
20
+ /** Application User Identity */
21
+ module.exports.Identity = require("./src/identity/identity");
18
22
  /** General Application */
19
23
  module.exports.notDomain = require("./src/domain");
20
24
  /** Mongoose Documents versioning */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "not-node",
3
- "version": "5.1.45",
3
+ "version": "6.0.1",
4
4
  "description": "node complimentary part for client side notFramework.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -47,6 +47,7 @@
47
47
  "express-session": "^1.17.3",
48
48
  "fs-extra": "*",
49
49
  "helmet": "^6.0.0",
50
+ "jsonwebtoken": "^8.5.1",
50
51
  "lower-case": "*",
51
52
  "method-override": "^3.0.0",
52
53
  "mock-require": "^3.0.3",
package/src/app.js CHANGED
@@ -1,4 +1,4 @@
1
- const Auth = require("./auth");
1
+ const notAppIdentity = require("./identity");
2
2
  const notDomain = require("./domain");
3
3
  const merge = require("deepmerge");
4
4
  const parent = require("../index.js");
@@ -50,7 +50,7 @@ class notApp extends notDomain {
50
50
  * @return {object} manifest
51
51
  **/
52
52
  getManifest(req) {
53
- const creds = Auth.extractAuthData(req);
53
+ const creds = notAppIdentity.extractAuthData(req);
54
54
  return this.collectManifest(creds);
55
55
  }
56
56
 
package/src/auth/index.js CHANGED
@@ -6,12 +6,10 @@ const FIELDS = require("./fields");
6
6
  const ROLES = require("./roles");
7
7
  const RULES = require("./rules");
8
8
  const ROUTES = require("./routes");
9
- const SESSION = require("./session");
10
9
 
11
10
  module.exports = {
12
11
  ...CONST,
13
12
  ...ABSTRACT,
14
- ...SESSION,
15
13
  ...ROLES,
16
14
  ...RULES,
17
15
  ...ROUTES,
@@ -1,45 +1,12 @@
1
- const log = require("not-log")(module, "Auth");
2
1
  const {
3
2
  HttpExceptionUnauthorized,
4
3
  HttpExceptionForbidden,
5
4
  } = require("../exceptions/http");
6
- const SESSION = require("./session");
7
- const ROLES = require("./roles");
8
-
9
- /**
10
- * Get request ip
11
- * @param {object} req Express Request
12
- **/
13
- function getIP(req) {
14
- if (req) {
15
- return (
16
- (req.headers && req.headers["x-forwarded-for"]) ||
17
- (req.connection && req.connection.remoteAddress) ||
18
- (req.socket && req.socket.remoteAddress) ||
19
- (req.connection &&
20
- req.connection.socket &&
21
- req.connection.socket.remoteAddress)
22
- );
23
- } else {
24
- return undefined;
25
- }
26
- }
27
5
 
28
- /**
29
- * Collects various authentification and authorization data from request object
30
- * @params {object} req ExpressRequest
31
- * @return {object} various authentification data for actor { root:boolean, auth: boolean, role: [string], uid: ObjectId, sid: string, ip:string }
32
- */
33
- function extractAuthData(req) {
34
- return {
35
- root: SESSION.isRoot(req),
36
- auth: SESSION.isUser(req),
37
- role: SESSION.getRole(req),
38
- uid: SESSION.getUserId(req),
39
- sid: SESSION.getSessionId(req),
40
- ip: getIP(req),
41
- };
42
- }
6
+ const { log } = require("not-log")(module, "Auth/Routes");
7
+ const ROLES = require("./roles");
8
+ const notAppIdentity = require("../identity");
9
+ const { getIP } = require("../common");
43
10
 
44
11
  /**
45
12
  * Returns Express middleware witch check role against one presented in request
@@ -48,8 +15,10 @@ function extractAuthData(req) {
48
15
  **/
49
16
  function checkRoleBuilder(role) {
50
17
  return (req, res, next) => {
51
- let userRole = SESSION.getRole(req);
52
- if (!SESSION.isUser(req)) {
18
+ const identity = new notAppIdentity(req);
19
+ const userRole = identity.getRole();
20
+ const userId = identity.getUserId();
21
+ if (!identity.isUser()) {
53
22
  return next(
54
23
  new HttpExceptionUnauthorized({
55
24
  params: { ip: getIP(req) },
@@ -63,8 +32,8 @@ function checkRoleBuilder(role) {
63
32
  new HttpExceptionForbidden({
64
33
  params: {
65
34
  ip: getIP(req),
66
- user: req.session.user,
67
- role: req.session.role,
35
+ user: userId,
36
+ role: userRole,
68
37
  },
69
38
  })
70
39
  );
@@ -73,14 +42,15 @@ function checkRoleBuilder(role) {
73
42
  }
74
43
 
75
44
  /**
76
- * Checks if user is authenticated, by searching req.session.user
45
+ * Checks if user is authenticated, by searching in Identity associated with request
77
46
  * If auth pass next, else throw error
78
47
  * @param {object} req Express Request object
79
48
  * @param {object} res Express Repost object
80
49
  * @param {function} next callback
81
50
  **/
82
51
  function checkUser(req, res, next) {
83
- if (SESSION.isUser(req)) {
52
+ const identity = new notAppIdentity(req);
53
+ if (identity.isUser()) {
84
54
  return next();
85
55
  } else {
86
56
  return next(
@@ -91,30 +61,18 @@ function checkUser(req, res, next) {
91
61
  }
92
62
  }
93
63
 
94
- /**
95
- * Checks if user is authenticated, by searching req.session.user
96
- * If auth pass next, else throw error
97
- * @param {object} req Express Request object
98
- * @param {object} res Express Repost object
99
- * @param {function} next callback
100
- **/
101
- function checkAdmin(req, res, next) {
102
- log.error("checkAdmin is obsolete, use new version as checkRoot");
103
- log.error(req.originalUrl);
104
- return checkRoot(req, res, next);
105
- }
106
-
107
64
  function checkRoot(req, res, next) {
108
- if (SESSION.isRoot(req)) {
65
+ const identity = new notAppIdentity(req);
66
+ if (identity.isRoot()) {
109
67
  return next();
110
68
  } else {
111
- if (SESSION.isUser(req)) {
69
+ if (identity.isUser()) {
112
70
  return next(
113
71
  new HttpExceptionForbidden({
114
72
  params: {
115
73
  ip: getIP(req),
116
- user: req.session.user,
117
- role: req.session.role,
74
+ user: identity.getUserId(),
75
+ role: identity.getRole(),
118
76
  },
119
77
  })
120
78
  );
@@ -128,9 +86,15 @@ function checkRoot(req, res, next) {
128
86
  }
129
87
  }
130
88
 
89
+ function extractAuthData(req) {
90
+ log(
91
+ "Obsolete path notAuth.extractAuthData(req), use notAppIdentity.extractAuthData(req) instead"
92
+ );
93
+ return notAppIdentity.extractAuthData(req);
94
+ }
95
+
131
96
  module.exports = {
132
97
  checkRoot,
133
- checkAdmin,
134
98
  checkUser,
135
99
  checkRoleBuilder,
136
100
  extractAuthData,
package/src/auth/rules.js CHANGED
@@ -1,15 +1,16 @@
1
1
  const ROLES = require("./roles");
2
2
  const postWarning = require("../obsolete");
3
+ const { objHas } = require("../common");
3
4
 
4
5
  function ruleHasRootDirective(rule) {
5
6
  return (
6
- (Object.prototype.hasOwnProperty.call(rule, "admin") && rule.admin) ||
7
- (Object.prototype.hasOwnProperty.call(rule, "root") && rule.root)
7
+ (objHas(rule, "admin") && rule.admin) ||
8
+ (objHas(rule, "root") && rule.root)
8
9
  );
9
10
  }
10
11
 
11
12
  function compareWithRoot(rule, root) {
12
- if (Object.prototype.hasOwnProperty.call(rule, "admin")) {
13
+ if (objHas(rule, "admin")) {
13
14
  return rule.admin && root;
14
15
  } else {
15
16
  return rule.root && root;
@@ -18,7 +19,7 @@ function compareWithRoot(rule, root) {
18
19
 
19
20
  function compareRuleRoles(rule, role, auth) {
20
21
  if (ROLES.compareRoles(rule.role, role)) {
21
- if (Object.prototype.hasOwnProperty.call(rule, "auth")) {
22
+ if (objHas(rule, "auth")) {
22
23
  if (rule.auth && auth) {
23
24
  return true;
24
25
  } else {
@@ -41,9 +42,9 @@ function roleRequireAuthState(requiredAuth, userAuth) {
41
42
  }
42
43
 
43
44
  function compareAuthStatus(rule, auth) {
44
- if (Object.prototype.hasOwnProperty.call(rule, "auth")) {
45
+ if (objHas(rule, "auth")) {
45
46
  return roleRequireAuthState(rule.auth, auth);
46
- } else if (Object.prototype.hasOwnProperty.call(rule, "user")) {
47
+ } else if (objHas(rule, "user")) {
47
48
  return roleRequireAuthState(rule.user, auth);
48
49
  } else {
49
50
  return true;
@@ -74,7 +75,7 @@ function checkCredentials(rule, auth, role, root) {
74
75
  return compareWithRoot(rule, root);
75
76
  } else {
76
77
  //if we have roles in rule, then using role based aproach
77
- if (Object.prototype.hasOwnProperty.call(rule, "role")) {
78
+ if (objHas(rule, "role")) {
78
79
  return compareRuleRoles(rule, role, auth);
79
80
  } else {
80
81
  //if no then just
package/src/common.js CHANGED
@@ -205,3 +205,22 @@ module.exports.generatePaths = (content = [], relative = "src") => {
205
205
  return prev;
206
206
  }, {});
207
207
  };
208
+
209
+ /**
210
+ * Get request ip
211
+ * @param {object} req Express Request
212
+ **/
213
+ module.exports.getIP = (req) => {
214
+ if (req) {
215
+ return (
216
+ (req.headers && req.headers["x-forwarded-for"]) ||
217
+ (req.connection && req.connection.remoteAddress) ||
218
+ (req.socket && req.socket.remoteAddress) ||
219
+ (req.connection &&
220
+ req.connection.socket &&
221
+ req.connection.socket.remoteAddress)
222
+ );
223
+ } else {
224
+ return undefined;
225
+ }
226
+ };
@@ -0,0 +1,17 @@
1
+ const { notError } = require("not-error");
2
+
3
+ class IdentityExceptionProviderAlreadySet extends notError {
4
+ constructor(name) {
5
+ super("not-node:identity_provider_already_set", { name });
6
+ }
7
+ }
8
+ module.exports.IdentityExceptionProviderAlreadySet =
9
+ IdentityExceptionProviderAlreadySet;
10
+
11
+ class IdentityExceptionProviderNotFound extends notError {
12
+ constructor() {
13
+ super("not-node:identity_provider_not_found");
14
+ }
15
+ }
16
+ module.exports.IdentityExceptionProviderNotFound =
17
+ IdentityExceptionProviderNotFound;
@@ -0,0 +1,61 @@
1
+ const { copyObj, objHas } = require("../common");
2
+ const IdentityProviderSession = require("./providers/session");
3
+ const IdentityProviderToken = require("./providers/token");
4
+ const {
5
+ IdentityExceptionProviderAlreadySet,
6
+ IdentityExceptionProviderNotFound,
7
+ } = require("./exceptions");
8
+
9
+ /**
10
+ * Class to manage and access to user identity providers and their options
11
+ */
12
+ class Identity {
13
+ static #priorities = ["token", "session"];
14
+
15
+ static #providers = {
16
+ session: IdentityProviderSession,
17
+ token: IdentityProviderToken,
18
+ };
19
+
20
+ static of(req) {
21
+ const Provider = this.providerSelector(req);
22
+ return new Provider(req);
23
+ }
24
+
25
+ static providerSelector(req) {
26
+ return this.getProvider(this.getProviderName(req));
27
+ }
28
+
29
+ static getProvider(providerName) {
30
+ return this.#providers[providerName];
31
+ }
32
+
33
+ // override if needed
34
+ static getProviderName(req) {
35
+ for (let providerName of this.#priorities) {
36
+ if (this.getProvider(providerName).test(req)) {
37
+ return providerName;
38
+ }
39
+ }
40
+ throw new IdentityExceptionProviderNotFound();
41
+ }
42
+
43
+ static setProviderOptions(providerName, options) {
44
+ if (options && typeof options !== "undefined") {
45
+ this.#providers[providerName].setOptions(copyObj(options));
46
+ }
47
+ }
48
+
49
+ static setProvider(providerName, Provider) {
50
+ if (objHas(this.#providers, providerName)) {
51
+ throw new IdentityExceptionProviderAlreadySet(providerName);
52
+ }
53
+ this.#providers[providerName] = Provider;
54
+ }
55
+
56
+ static setProvidersPriorities(list = []) {
57
+ this.#priorities = [...list];
58
+ }
59
+ }
60
+
61
+ module.exports = Identity;
@@ -0,0 +1,35 @@
1
+ const Identity = require("./identity");
2
+ const { getIP } = require("../common");
3
+
4
+ module.exports = class notAppIdentity {
5
+ static #identity = Identity;
6
+
7
+ static set identity(val) {
8
+ this.#identity = val;
9
+ }
10
+
11
+ static get identity() {
12
+ return this.#identity;
13
+ }
14
+
15
+ /**
16
+ * Collects various authentification and authorization data from request object
17
+ * @params {object} req ExpressRequest
18
+ * @return {object} various authentification data for actor { root:boolean, auth: boolean, role: [string], uid: ObjectId, sid: string, ip:string }
19
+ */
20
+ static extractAuthData(req) {
21
+ const identity = this.#identity.of(req);
22
+ return {
23
+ root: identity.isRoot(),
24
+ auth: identity.isUser(),
25
+ role: identity.getRole(),
26
+ uid: identity.getUserId(),
27
+ sid: identity.getSessionId(),
28
+ ip: getIP(req),
29
+ };
30
+ }
31
+
32
+ constructor(req) {
33
+ return notAppIdentity.identity.of(req);
34
+ }
35
+ };
@@ -0,0 +1,137 @@
1
+ const CONST = require("../../auth/const");
2
+ const ROLES = require("../../auth/roles");
3
+
4
+ module.exports = class IdentityProviderSession {
5
+ static #options = {};
6
+
7
+ static setOptions(options = {}) {
8
+ this.#options = options;
9
+ }
10
+
11
+ static #getOptions() {
12
+ return this.#options;
13
+ }
14
+
15
+ constructor(req) {
16
+ this.req = req;
17
+ return this;
18
+ }
19
+
20
+ /**
21
+ * Checks if user is authenticated, by searching req.session.user
22
+ * @return {boolean} true - authenticated, false - guest
23
+ **/
24
+
25
+ isUser() {
26
+ const req = this.req;
27
+ return req && req.session && req.session.user ? true : false;
28
+ }
29
+
30
+ /**
31
+ * Returns user role from request object
32
+ * @return user role
33
+ **/
34
+ getRole() {
35
+ const req = this.req;
36
+ return req && req.session && req.session.role
37
+ ? req.session.role
38
+ : undefined;
39
+ }
40
+
41
+ /**
42
+ * Set user role for active session
43
+ * @param {Array<string>} role array of roles
44
+ **/
45
+ setRole(role) {
46
+ const req = this.req;
47
+ if (req && req.session) {
48
+ req.session.role = role;
49
+ req.session.save();
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Set user id for active session
55
+ * @param {string} _id user id
56
+ **/
57
+ setUserId(_id) {
58
+ const req = this.req;
59
+ if (req && req.session) {
60
+ req.session.user = _id;
61
+ req.session.save();
62
+ }
63
+ }
64
+
65
+ isRoot() {
66
+ return (
67
+ this.isUser() &&
68
+ ROLES.compareRoles(
69
+ this.getRole(),
70
+ CONST.DEFAULT_USER_ROLE_FOR_ADMIN
71
+ )
72
+ );
73
+ }
74
+
75
+ /**
76
+ * Get user id for active session
77
+ **/
78
+ getUserId() {
79
+ const req = this.req;
80
+ if (req && req.session) {
81
+ return req.session.user;
82
+ } else {
83
+ return undefined;
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Get session id for active session
89
+ **/
90
+ getSessionId() {
91
+ const req = this.req;
92
+ if (req && req.session && req.session.id) {
93
+ return req.session.id.toString();
94
+ } else {
95
+ return undefined;
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Set auth data in session, user id and role
101
+ * @param {string} id user id
102
+ * @param {string} role user role
103
+ **/
104
+ setAuth(id, role) {
105
+ this.setUserId(id);
106
+ this.setRole(role);
107
+ }
108
+
109
+ /**
110
+ * Set auth data in session to Guest
111
+ **/
112
+ setGuest() {
113
+ const req = this.req;
114
+ if (req && req.session) {
115
+ req.user = null;
116
+ req.session.user = null;
117
+ this.setRole([CONST.DEFAULT_USER_ROLE_FOR_GUEST]);
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Reset session
123
+ **/
124
+ cleanse() {
125
+ const req = this.req;
126
+ if (req && req.session) {
127
+ this.setGuest();
128
+ if (req.session.destroy) {
129
+ req.session.destroy();
130
+ }
131
+ }
132
+ }
133
+
134
+ static test(req) {
135
+ return typeof req.session !== "undefined" && req.session !== null;
136
+ }
137
+ };