Skip to content

Commit 5f07fa9

Browse files
mtrezzaArul-
authored andcommitted
Add circular dependency detection to CI (parse-community#7316)
* add circular dependency detection to CI * fixed Auth-RestWrite circular dependency * updated package lock * fixed Logger circular dependency * fix lint
1 parent d13c12a commit 5f07fa9

File tree

8 files changed

+66
-46
lines changed

8 files changed

+66
-46
lines changed

.github/workflows/ci.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,26 @@ jobs:
5252
- name: Install dependencies
5353
run: npm ci
5454
- run: npm run lint
55+
check-circular:
56+
name: Circular Dependencies
57+
timeout-minutes: 5
58+
runs-on: ubuntu-18.04
59+
steps:
60+
- uses: actions/checkout@v2
61+
- name: Use Node.js ${{ matrix.NODE_VERSION }}
62+
uses: actions/setup-node@v1
63+
with:
64+
node-version: ${{ matrix.node-version }}
65+
- name: Cache Node.js modules
66+
uses: actions/cache@v2
67+
with:
68+
path: ~/.npm
69+
key: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }}
70+
restore-keys: |
71+
${{ runner.os }}-node-${{ matrix.NODE_VERSION }}-
72+
- name: Install dependencies
73+
run: npm ci
74+
- run: npm run madge:circular
5575
check-mongo:
5676
strategy:
5777
matrix:

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
"jsdoc": "3.6.3",
9292
"jsdoc-babel": "0.5.0",
9393
"lint-staged": "10.2.3",
94+
"madge": "4.0.2",
9495
"mock-mail-adapter": "file:spec/support/MockMailAdapter",
9596
"mongodb-runner": "4.8.1",
9697
"mongodb-version-list": "1.0.0",
@@ -122,7 +123,8 @@
122123
"start": "node ./bin/parse-server",
123124
"prettier": "prettier --write '{src,spec}/{**/*,*}.js'",
124125
"prepare": "npm run build",
125-
"postinstall": "node -p 'require(\"./postinstall.js\")()'"
126+
"postinstall": "node -p 'require(\"./postinstall.js\")()'",
127+
"madge:circular": "node_modules/.bin/madge ./src --circular"
126128
},
127129
"engines": {
128130
"node": ">= 8"

src/Auth.js

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
const cryptoUtils = require('./cryptoUtils');
21
const RestQuery = require('./RestQuery');
32
const Parse = require('parse/node');
43

@@ -299,45 +298,11 @@ Auth.prototype._getAllRolesNamesForRoleIds = function (roleIDs, names = [], quer
299298
});
300299
};
301300

302-
const createSession = function (
303-
config,
304-
{ userId, createdWith, installationId, additionalSessionData }
305-
) {
306-
const token = 'r:' + cryptoUtils.newToken();
307-
const expiresAt = config.generateSessionExpiresAt();
308-
const sessionData = {
309-
sessionToken: token,
310-
user: {
311-
__type: 'Pointer',
312-
className: '_User',
313-
objectId: userId,
314-
},
315-
createdWith,
316-
restricted: false,
317-
expiresAt: Parse._encode(expiresAt),
318-
};
319-
320-
if (installationId) {
321-
sessionData.installationId = installationId;
322-
}
323-
324-
Object.assign(sessionData, additionalSessionData);
325-
// We need to import RestWrite at this point for the cyclic dependency it has to it
326-
const RestWrite = require('./RestWrite');
327-
328-
return {
329-
sessionData,
330-
createSession: () =>
331-
new RestWrite(config, master(config), '_Session', null, sessionData).execute(),
332-
};
333-
};
334-
335301
module.exports = {
336302
Auth,
337303
master,
338304
nobody,
339305
readOnly,
340306
getAuthForSessionToken,
341307
getAuthForLegacySessionToken,
342-
createSession,
343308
};

src/Controllers/AdaptableController.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ based on the parameters passed
1010

1111
// _adapter is private, use Symbol
1212
var _adapter = Symbol();
13-
import Config from '../Config';
1413

1514
export class AdaptableController {
1615
constructor(adapter, appId, options) {
@@ -28,10 +27,6 @@ export class AdaptableController {
2827
return this[_adapter];
2928
}
3029

31-
get config() {
32-
return Config.get(this.appId);
33-
}
34-
3530
expectedAdapterType() {
3631
throw new Error('Subclasses should implement expectedAdapterType()');
3732
}

src/Controllers/UserController.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import MailAdapter from '../Adapters/Email/MailAdapter';
55
import rest from '../rest';
66
import Parse from 'parse/node';
77
import AccountLockout from '../AccountLockout';
8+
import Config from '../Config';
89

910
var RestQuery = require('../RestQuery');
1011
var Auth = require('../Auth');
@@ -14,6 +15,10 @@ export class UserController extends AdaptableController {
1415
super(adapter, appId, options);
1516
}
1617

18+
get config() {
19+
return Config.get(this.appId);
20+
}
21+
1722
validateAdapter(adapter) {
1823
// Allow no adapter
1924
if (!adapter && !this.shouldVerifyEmails) {

src/RestWrite.js

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,7 @@ RestWrite.prototype.createSessionToken = async function () {
857857
return;
858858
}
859859

860-
const { sessionData, createSession } = Auth.createSession(this.config, {
860+
const { sessionData, createSession } = RestWrite.createSession(this.config, {
861861
userId: this.objectId(),
862862
createdWith: {
863863
action: this.storage['authProvider'] ? 'login' : 'signup',
@@ -873,6 +873,37 @@ RestWrite.prototype.createSessionToken = async function () {
873873
return createSession();
874874
};
875875

876+
RestWrite.createSession = function (
877+
config,
878+
{ userId, createdWith, installationId, additionalSessionData }
879+
) {
880+
const token = 'r:' + cryptoUtils.newToken();
881+
const expiresAt = config.generateSessionExpiresAt();
882+
const sessionData = {
883+
sessionToken: token,
884+
user: {
885+
__type: 'Pointer',
886+
className: '_User',
887+
objectId: userId,
888+
},
889+
createdWith,
890+
restricted: false,
891+
expiresAt: Parse._encode(expiresAt),
892+
};
893+
894+
if (installationId) {
895+
sessionData.installationId = installationId;
896+
}
897+
898+
Object.assign(sessionData, additionalSessionData);
899+
900+
return {
901+
sessionData,
902+
createSession: () =>
903+
new RestWrite(config, Auth.master(config), '_Session', null, sessionData).execute(),
904+
};
905+
};
906+
876907
// Delete email reset tokens if user is changing password or email.
877908
RestWrite.prototype.deleteEmailResetTokenIfNeeded = function () {
878909
if (this.className !== '_User' || this.query === null) {
@@ -978,7 +1009,7 @@ RestWrite.prototype.handleSession = function () {
9781009
additionalSessionData[key] = this.data[key];
9791010
}
9801011

981-
const { sessionData, createSession } = Auth.createSession(this.config, {
1012+
const { sessionData, createSession } = RestWrite.createSession(this.config, {
9821013
userId: this.auth.user.id,
9831014
createdWith: {
9841015
action: 'create',
@@ -1258,7 +1289,7 @@ RestWrite.prototype.handleInstallation = function () {
12581289
return promise;
12591290
};
12601291

1261-
// If we short-circuted the object response - then we need to make sure we expand all the files,
1292+
// If we short-circuited the object response - then we need to make sure we expand all the files,
12621293
// since this might not have a query, meaning it won't return the full result back.
12631294
// TODO: (nlutsenko) This should die when we move to per-class based controllers on _Session/_User
12641295
RestWrite.prototype.expandFilesForExistingObjects = function () {

src/Routers/SessionsRouter.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import ClassesRouter from './ClassesRouter';
22
import Parse from 'parse/node';
33
import rest from '../rest';
44
import Auth from '../Auth';
5+
import RestWrite from '../RestWrite';
56

67
export class SessionsRouter extends ClassesRouter {
78
className() {
@@ -41,7 +42,7 @@ export class SessionsRouter extends ClassesRouter {
4142
if (!user) {
4243
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'invalid session');
4344
}
44-
const { sessionData, createSession } = Auth.createSession(config, {
45+
const { sessionData, createSession } = RestWrite.createSession(config, {
4546
userId: user.id,
4647
createdWith: {
4748
action: 'upgrade',

src/Routers/UsersRouter.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Auth from '../Auth';
99
import passwordCrypto from '../password';
1010
import { maybeRunTrigger, Types as TriggerTypes } from '../triggers';
1111
import { promiseEnsureIdempotency } from '../middlewares';
12+
import RestWrite from '../RestWrite';
1213

1314
export class UsersRouter extends ClassesRouter {
1415
className() {
@@ -218,7 +219,7 @@ export class UsersRouter extends ClassesRouter {
218219
req.config
219220
);
220221

221-
const { sessionData, createSession } = Auth.createSession(req.config, {
222+
const { sessionData, createSession } = RestWrite.createSession(req.config, {
222223
userId: user.objectId,
223224
createdWith: {
224225
action: 'login',

0 commit comments

Comments
 (0)