Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 0 additions & 37 deletions spec/Auth.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,20 +114,6 @@ describe('Auth', () => {
expect(session.get('expiresAt') > expiry).toBeTrue();
});

it('should load auth without a config', async () => {
const user = new Parse.User();
await user.signUp({
username: 'hello',
password: 'password',
});
expect(user.getSessionToken()).not.toBeUndefined();
const userAuth = await getAuthForSessionToken({
sessionToken: user.getSessionToken(),
});
expect(userAuth.user instanceof Parse.User).toBe(true);
expect(userAuth.user.id).toBe(user.id);
});

it('should load auth with a config', async () => {
const user = new Parse.User();
await user.signUp({
Expand All @@ -146,29 +132,6 @@ describe('Auth', () => {
describe('getRolesForUser', () => {
const rolesNumber = 100;

it('should load all roles without config', async () => {
const user = new Parse.User();
await user.signUp({
username: 'hello',
password: 'password',
});
expect(user.getSessionToken()).not.toBeUndefined();
const userAuth = await getAuthForSessionToken({
sessionToken: user.getSessionToken(),
});
const roles = [];
for (let i = 0; i < rolesNumber; i++) {
const acl = new Parse.ACL();
const role = new Parse.Role('roleloadtest' + i, acl);
role.getUsers().add([user]);
roles.push(role);
}
const savedRoles = await Parse.Object.saveAll(roles);
expect(savedRoles.length).toBe(rolesNumber);
const cloudRoles = await userAuth.getRolesForUser();
expect(cloudRoles.length).toBe(rolesNumber);
});

it('should load all roles with config', async () => {
const user = new Parse.User();
await user.signUp({
Expand Down
13 changes: 13 additions & 0 deletions spec/CloudCode.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2673,6 +2673,19 @@ describe('beforeFind hooks', () => {
});
});

it('should preserve a falsy query override from beforeFind (limit 0)', async () => {
Parse.Cloud.beforeFind('MyObject', req => {
req.query.limit(0);
});

const obj0 = new Parse.Object('MyObject');
const obj1 = new Parse.Object('MyObject');
await Parse.Object.saveAll([obj0, obj1]);

const results = await new Parse.Query('MyObject').find();
expect(results.length).toBe(0);
});

it('should have object found with nested relational data query', async () => {
const obj1 = Parse.Object.extend('TestObject');
const obj2 = Parse.Object.extend('TestObject2');
Expand Down
73 changes: 17 additions & 56 deletions spec/ParseLiveQueryServer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1506,34 +1506,16 @@ describe('ParseLiveQueryServer', function () {
};
const requestId = 0;

spyOn(Parse, 'Query').and.callFake(function () {
let shouldReturn = false;
return {
equalTo() {
shouldReturn = true;
// Nothing to do here
return this;
// The user has the "liveQueryRead" role, but the ACL only grants read access
// to "otherLiveQueryRead", so it should not match.
spyOn(parseLiveQueryServer, 'getAuthForSessionToken').and.returnValue(
Promise.resolve({
userId: 'someUserId',
auth: {
getUserRoles: () => Promise.resolve(['role:liveQueryRead']),
},
containedIn() {
shouldReturn = false;
return this;
},
find() {
if (!shouldReturn) {
return Promise.resolve([]);
}
//Return a role with the name "liveQueryRead" as that is what was set on the ACL
const liveQueryRole = new Parse.Role('liveQueryRead', new Parse.ACL());
liveQueryRole.id = 'abcdef1234';
return Promise.resolve([liveQueryRole]);
},
};
});

parseLiveQueryServer._matchesACL(acl, client, requestId).then(function (isMatched) {
expect(isMatched).toBe(false);
done();
});
})
);
Comment on lines +1511 to +1518
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect getAuthForSessionToken's return shape and how _matchesACL consumes it.
fd -t f 'ParseLiveQueryServer.ts' --exec rg -nP -C4 'getAuthForSessionToken|getUserRoles|userId|_matchesACL|_matchesACLWithSessionToken' {}

Repository: parse-community/parse-server

Length of output: 7730


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the exact functions that consume getAuthForSessionToken and where auth.getUserRoles()/userId are used
fd -t f 'ParseLiveQueryServer.ts' --exec rg -n --color=never 'getAuthForSessionToken\(|getUserRoles\(|_matchesACLWithSessionToken|_matchesACL\(' {} \
  | head -n 50

# Print the relevant surrounding blocks (avoid whole-file dumps)
fd -t f 'ParseLiveQueryServer.ts' --exec bash -lc 'sed -n "640,740p" "$1"; echo "-----"; sed -n "760,910p" "$1"' bash {}

Repository: parse-community/parse-server

Length of output: 9190


🏁 Script executed:

#!/bin/bash
set -euo pipefail

f=$(fd -t f 'ParseLiveQueryServer.ts' | head -n 1)
echo "Using: $f"

# Print the remainder of _matchesACL and the call into ACL/role verification
python3 - <<'PY'
import re, pathlib
path = pathlib.Path("".join([""])).resolve()
PY
# fallback to sed windows; adjust by printing larger region around _matchesACL start
sed -n '900,1100p' "$f"

Repository: parse-community/parse-server

Length of output: 7103


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1450,1605p' spec/ParseLiveQueryServer.spec.js | nl -ba | sed -n '1,200p'

Repository: parse-community/parse-server

Length of output: 115


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the exact test cases around the stubbed getAuthForSessionToken usage (avoid huge output)
python3 - <<'PY'
import itertools, pathlib
p = pathlib.Path("spec/ParseLiveQueryServer.spec.js")
start, end = 1470, 1570
lines = p.read_text().splitlines()
for i in range(start-1, min(end, len(lines))):
    print(f"{i+1}: {lines[i]}")
PY

Repository: parse-community/parse-server

Length of output: 3954


Update: the getAuthForSessionToken stub shape matches _matchesACL/_verifyACL role checks

The stub’s return { userId, auth: { getUserRoles } } matches _verifyACL’s usage (const { auth, userId } = await ...; roleNames = await auth.getUserRoles(); acl.getReadAccess(role)), and the returned roles use the expected role:<name> form.

The two .then(...) chains in these tests (for lines ~1511-1524 and ~1539-1552) still lack .catch(done.fail) unlike the neighboring test, so a rejection could leave the spec hanging.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@spec/ParseLiveQueryServer.spec.js` around lines 1511 - 1518, Two promise
chains in the tests that stub parseLiveQueryServer.getAuthForSessionToken (the
blocks that return { userId, auth: { getUserRoles } }) are missing error
handlers and can leave the spec hanging; update each of those .then(...) chains
to append .catch(done.fail) so rejections cause the test to fail and complete
(i.e., locate the tests that spyOn parseLiveQueryServer.getAuthForSessionToken
and add .catch(done.fail) to both promise chains).


parseLiveQueryServer._matchesACL(acl, client, requestId).then(function (isMatched) {
expect(isMatched).toBe(false);
Expand All @@ -1553,36 +1535,15 @@ describe('ParseLiveQueryServer', function () {
};
const requestId = 0;

spyOn(Parse, 'Query').and.callFake(function () {
let shouldReturn = false;
return {
equalTo() {
shouldReturn = true;
// Nothing to do here
return this;
},
containedIn() {
shouldReturn = false;
return this;
},
find() {
if (!shouldReturn) {
return Promise.resolve([]);
}
//Return a role with the name "liveQueryRead" as that is what was set on the ACL
const liveQueryRole = new Parse.Role('liveQueryRead', new Parse.ACL());
liveQueryRole.id = 'abcdef1234';
return Promise.resolve([liveQueryRole]);
},
each(callback) {
//Return a role with the name "liveQueryRead" as that is what was set on the ACL
const liveQueryRole = new Parse.Role('liveQueryRead', new Parse.ACL());
liveQueryRole.id = 'abcdef1234';
callback(liveQueryRole);
return Promise.resolve();
// The user has the "liveQueryRead" role, which the ACL grants read access to.
spyOn(parseLiveQueryServer, 'getAuthForSessionToken').and.returnValue(
Promise.resolve({
userId: 'someUserId',
auth: {
getUserRoles: () => Promise.resolve(['role:liveQueryRead']),
},
};
});
})
);

parseLiveQueryServer._matchesACL(acl, client, requestId).then(function (isMatched) {
expect(isMatched).toBe(true);
Expand Down
4 changes: 0 additions & 4 deletions spec/ParseRole.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,6 @@ describe('Parse Role testing', () => {
testLoadRoles(Config.get('test'), done);
});

it('should recursively load roles without config', done => {
testLoadRoles(undefined, done);
});

it('_Role object should not save without name.', done => {
const role = new Parse.Role();
role.save(null, { useMasterKey: true }).then(
Expand Down
54 changes: 0 additions & 54 deletions spec/SessionTokenCache.spec.js

This file was deleted.

Loading
Loading