Skip to content

Commit 8d4528e

Browse files
committed
feature: add dynamic publicServerUrl
1 parent d14a723 commit 8d4528e

File tree

4 files changed

+43
-3
lines changed

4 files changed

+43
-3
lines changed

spec/index.spec.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,17 @@ describe('server', () => {
615615
expect(config.masterKeyCache.expiresAt.getTime()).toBeGreaterThan(Date.now());
616616
});
617617

618+
it('should load publicServerURL', async () => {
619+
await reconfigureServer({
620+
publicServerURL: () => 'https://myserver.com/1',
621+
});
622+
623+
await new Parse.Object('TestObject').save();
624+
625+
const config = Config.get(Parse.applicationId);
626+
expect(config.publicServerURL).toEqual('https://myserver.com/1');
627+
});
628+
618629
it('should not reload if ttl is not set', async () => {
619630
const masterKeySpy = jasmine.createSpy().and.returnValue(Promise.resolve('initialMasterKey'));
620631

src/Config.js

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ function removeTrailingSlash(str) {
3232
return str;
3333
}
3434

35+
const asyncKeys = ['publicServerURL'];
3536
export class Config {
3637
static get(applicationId: string, mount: string) {
3738
const cacheInfo = AppCache.get(applicationId);
@@ -56,9 +57,33 @@ export class Config {
5657
return config;
5758
}
5859

60+
async loadKeys() {
61+
const asyncKeys = ['publicServerURL'];
62+
63+
await Promise.all(
64+
asyncKeys.map(async key => {
65+
if (typeof this[`_${key}`] === 'function') {
66+
this[key] = await this[`_${key}`]();
67+
}
68+
})
69+
);
70+
71+
Config.put(this);
72+
}
73+
74+
static transformConfiguration(serverConfiguration) {
75+
for (const key of Object.keys(serverConfiguration)) {
76+
if (asyncKeys.includes(key) && typeof serverConfiguration[key] === 'function') {
77+
serverConfiguration[`_${key}`] = serverConfiguration[key];
78+
delete serverConfiguration[key];
79+
}
80+
}
81+
}
82+
5983
static put(serverConfiguration) {
6084
Config.validateOptions(serverConfiguration);
6185
Config.validateControllers(serverConfiguration);
86+
Config.transformConfiguration(serverConfiguration);
6287
AppCache.put(serverConfiguration.appId, serverConfiguration);
6388
Config.setupPasswordValidator(serverConfiguration.passwordPolicy);
6489
return serverConfiguration;
@@ -116,7 +141,11 @@ export class Config {
116141
}
117142

118143
if (publicServerURL) {
119-
if (!publicServerURL.startsWith('http://') && !publicServerURL.startsWith('https://')) {
144+
if (
145+
typeof publicServerURL !== 'function' &&
146+
!publicServerURL.startsWith('http://') &&
147+
!publicServerURL.startsWith('https://')
148+
) {
120149
throw 'publicServerURL should be a valid HTTPS URL starting with https://';
121150
}
122151
}
@@ -757,7 +786,6 @@ export class Config {
757786
return this.masterKey;
758787
}
759788

760-
761789
// TODO: Remove this function once PagesRouter replaces the PublicAPIRouter;
762790
// the (default) endpoint has to be defined in PagesRouter only.
763791
get pagesEndpoint() {

src/middlewares.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ export async function handleParseHeaders(req, res, next) {
213213
});
214214
return;
215215
}
216+
await config.loadKeys();
216217

217218
info.app = AppCache.get(info.appId);
218219
req.config = config;

types/Options/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export interface ParseServerOptions {
8585
cacheAdapter?: Adapter<CacheAdapter>;
8686
emailAdapter?: Adapter<MailAdapter>;
8787
encodeParseObjectInCloudFunction?: boolean;
88-
publicServerURL?: string;
88+
publicServerURL?: string | (() => string) | Promise<string>;
8989
pages?: PagesOptions;
9090
customPages?: CustomPagesOptions;
9191
liveQuery?: LiveQueryOptions;

0 commit comments

Comments
 (0)