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
82 changes: 82 additions & 0 deletions spec/PasswordResetLink.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
'use strict';

describe('Password Reset Link', () => {
it('should generate a password reset link with actual appId, not {appId} or undefined', async () => {
let emailLinkReceived = null;

Check failure on line 6 in spec/PasswordResetLink.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Trailing spaces not allowed
const emailAdapter = {
sendVerificationEmail: () => Promise.resolve(),
sendPasswordResetEmail: options => {
emailLinkReceived = options.link;
// Check that the link contains the actual appId ('test'), not the literal string '{appId}'
expect(options.link).toBeDefined();
expect(options.link).not.toContain('{appId}');
expect(options.link).toContain('/test/');
return Promise.resolve();
},
sendMail: () => Promise.resolve(),
};

await reconfigureServer({
appId: 'test',
appName: 'Test App',
verifyUserEmails: true,
emailAdapter: emailAdapter,
publicServerURL: 'http://localhost:8378/1',
});

const user = new Parse.User();
user.setPassword('password');
user.setUsername('testuser');
user.set('email', '[email protected]');
await user.signUp();

Check failure on line 33 in spec/PasswordResetLink.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Trailing spaces not allowed
await Parse.User.requestPasswordReset('[email protected]');

Check failure on line 35 in spec/PasswordResetLink.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Trailing spaces not allowed
// Verify the link was generated correctly
expect(emailLinkReceived).not.toBeNull();
expect(emailLinkReceived).toMatch(/\/test\/request_password_reset\?token=/);
});

Check failure on line 40 in spec/PasswordResetLink.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Trailing spaces not allowed
it('should render password reset page with actual appId in form action', async () => {
const emailAdapter = {
sendVerificationEmail: () => Promise.resolve(),
sendPasswordResetEmail: () => Promise.resolve(),
sendMail: () => Promise.resolve(),
};

await reconfigureServer({
appId: 'test',
appName: 'Test App',
verifyUserEmails: true,
emailAdapter: emailAdapter,
publicServerURL: 'http://localhost:8378/1',
});

const user = new Parse.User();
user.setPassword('password');
user.setUsername('testuser2');
user.set('email', '[email protected]');
await user.signUp();

Check failure on line 61 in spec/PasswordResetLink.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Trailing spaces not allowed
// Trigger password reset to get a token
await Parse.User.requestPasswordReset('[email protected]');

Check failure on line 64 in spec/PasswordResetLink.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Trailing spaces not allowed
// Find the user to get the reset token
const results = await new Parse.Query('_User')
.equalTo('email', '[email protected]')
.find({ useMasterKey: true });
const resetToken = results[0].get('_perishable_token');

Check failure on line 70 in spec/PasswordResetLink.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Trailing spaces not allowed
// Request the password reset page
const response = await request({

Check failure on line 72 in spec/PasswordResetLink.spec.js

View workflow job for this annotation

GitHub Actions / Lint

'request' is not defined
url: `http://localhost:8378/1/apps/test/request_password_reset?token=${resetToken}`,
followRedirects: false,
});

Check failure on line 76 in spec/PasswordResetLink.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Trailing spaces not allowed
expect(response.status).toBe(200);
// The form action should contain the actual appId 'test', not '{appId}'
expect(response.text).toContain('/apps/test/request_password_reset');
expect(response.text).not.toContain('{appId}');
});
});
6 changes: 3 additions & 3 deletions src/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class Config {
Object.keys(cacheInfo).forEach(key => {
if (key == 'databaseController') {
config.database = new DatabaseController(cacheInfo.databaseController.adapter, config);
} else {
} else if (key !== 'applicationId') {
config[key] = cacheInfo[key];
}
});
Expand Down Expand Up @@ -789,7 +789,7 @@ export class Config {
}

get requestResetPasswordURL() {
return `${this.publicServerURL}/${this.pagesEndpoint}/${this.applicationId}/request_password_reset`;
return `${this.publicServerURL}/${this.pagesEndpoint}/${this.appId}/request_password_reset`;
}

get passwordResetSuccessURL() {
Expand All @@ -804,7 +804,7 @@ export class Config {
}

get verifyEmailURL() {
return `${this.publicServerURL}/${this.pagesEndpoint}/${this.applicationId}/verify_email`;
return `${this.publicServerURL}/${this.pagesEndpoint}/${this.appId}/verify_email`;
}

async loadMasterKey() {
Expand Down
4 changes: 2 additions & 2 deletions src/Routers/PagesRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export class PagesRouter extends PromiseRouter {
() => {
const params = {
[pageParams.token]: token,
[pageParams.appId]: config.applicationId,
[pageParams.appId]: config.appId,
[pageParams.appName]: config.appName,
};
return this.goToPage(req, pages.passwordReset, params);
Expand Down Expand Up @@ -225,7 +225,7 @@ export class PagesRouter extends PromiseRouter {
? {}
: {
[pageParams.token]: token,
[pageParams.appId]: config.applicationId,
[pageParams.appId]: config.appId,
[pageParams.error]: result.err,
[pageParams.appName]: config.appName,
};
Expand Down
Loading