Skip to content

Commit 8471e75

Browse files
mmermerkayaFeiyang1
authored andcommitted
Use appName + appId to key installation entries (#116)
Also changes idb manager functions to get the key from the app config.
1 parent e198386 commit 8471e75

11 files changed

+145
-107
lines changed

packages/installations/src/api.test.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
RequestStatus
3636
} from './interfaces/installation-entry';
3737
import { compareHeaders } from './testing/compare-headers';
38+
import { getFakeAppConfig } from './testing/get-fake-app';
3839
import './testing/setup';
3940

4041
const FID = 'defenders-of-the-faith';
@@ -44,11 +45,7 @@ describe('api', () => {
4445
let fetchSpy: SinonStub<[RequestInfo, RequestInit?], Promise<Response>>;
4546

4647
beforeEach(async () => {
47-
appConfig = {
48-
apiKey: 'apiKey',
49-
projectId: 'projectId',
50-
appId: '1:777777777777:web:d93b5ca1475efe57'
51-
};
48+
appConfig = getFakeAppConfig();
5249
});
5350

5451
afterEach(() => {

packages/installations/src/get-auth-token.test.ts

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
} from './interfaces/installation-entry';
3434
import { getFakeApp } from './testing/get-fake-app';
3535
import './testing/setup';
36+
import { extractAppConfig } from './util/extract-app-config';
3637
import { sleep } from './util/sleep';
3738

3839
const FID = 'dont-talk-to-strangers';
@@ -43,10 +44,13 @@ const ONE_WEEK_MS = 7 * 24 * 60 * 60 * 1000;
4344
* A map of different states of the database and a function that creates the
4445
* said state.
4546
*/
46-
const setupInstallationEntryMap: Map<string, () => Promise<void>> = new Map([
47+
const setupInstallationEntryMap: Map<
48+
string,
49+
(appConfig: AppConfig) => Promise<void>
50+
> = new Map([
4751
[
4852
'existing and valid auth token',
49-
async () => {
53+
async (appConfig: AppConfig) => {
5054
const entry: RegisteredInstallationEntry = {
5155
fid: FID,
5256
registrationStatus: RequestStatus.COMPLETED,
@@ -58,12 +62,12 @@ const setupInstallationEntryMap: Map<string, () => Promise<void>> = new Map([
5862
creationTime: Date.now()
5963
}
6064
};
61-
set('appId', entry);
65+
set(appConfig, entry);
6266
}
6367
],
6468
[
6569
'expired auth token',
66-
async () => {
70+
async (appConfig: AppConfig) => {
6771
const entry: RegisteredInstallationEntry = {
6872
fid: FID,
6973
registrationStatus: RequestStatus.COMPLETED,
@@ -75,12 +79,12 @@ const setupInstallationEntryMap: Map<string, () => Promise<void>> = new Map([
7579
creationTime: Date.now() - 2 * ONE_WEEK_MS
7680
}
7781
};
78-
set('appId', entry);
82+
set(appConfig, entry);
7983
}
8084
],
8185
[
8286
'pending auth token',
83-
async () => {
87+
async (appConfig: AppConfig) => {
8488
const entry: RegisteredInstallationEntry = {
8589
fid: FID,
8690
registrationStatus: RequestStatus.COMPLETED,
@@ -91,7 +95,7 @@ const setupInstallationEntryMap: Map<string, () => Promise<void>> = new Map([
9195
}
9296
};
9397

94-
set('appId', entry);
98+
set(appConfig, entry);
9599

96100
// Finish pending request in 10 ms
97101
sleep(50).then(() => {
@@ -104,13 +108,13 @@ const setupInstallationEntryMap: Map<string, () => Promise<void>> = new Map([
104108
creationTime: Date.now()
105109
}
106110
};
107-
set('appId', updatedEntry);
111+
set(appConfig, updatedEntry);
108112
});
109113
}
110114
],
111115
[
112116
'no auth token',
113-
async () => {
117+
async (appConfig: AppConfig) => {
114118
const entry: RegisteredInstallationEntry = {
115119
fid: FID,
116120
registrationStatus: RequestStatus.COMPLETED,
@@ -119,19 +123,19 @@ const setupInstallationEntryMap: Map<string, () => Promise<void>> = new Map([
119123
requestStatus: RequestStatus.NOT_STARTED
120124
}
121125
};
122-
set('appId', entry);
126+
set(appConfig, entry);
123127
}
124128
],
125129
[
126130
'pending fid registration',
127-
async () => {
131+
async (appConfig: AppConfig) => {
128132
const entry: InProgressInstallationEntry = {
129133
fid: FID,
130134
registrationStatus: RequestStatus.IN_PROGRESS,
131135
registrationTime: Date.now() - 3 * 1000
132136
};
133137

134-
set('appId', entry);
138+
set(appConfig, entry);
135139

136140
// Finish pending request in 10 ms
137141
sleep(50).then(async () => {
@@ -146,25 +150,26 @@ const setupInstallationEntryMap: Map<string, () => Promise<void>> = new Map([
146150
creationTime: Date.now()
147151
}
148152
};
149-
set('appId', updatedEntry);
153+
set(appConfig, updatedEntry);
150154
});
151155
}
152156
],
153157
[
154158
'unregistered fid',
155-
async () => {
159+
async (appConfig: AppConfig) => {
156160
const entry: UnregisteredInstallationEntry = {
157161
fid: FID,
158162
registrationStatus: RequestStatus.NOT_STARTED
159163
};
160164

161-
set('appId', entry);
165+
set(appConfig, entry);
162166
}
163167
]
164168
]);
165169

166170
describe('getAuthToken', () => {
167-
const app: FirebaseApp = getFakeApp();
171+
let app: FirebaseApp;
172+
let appConfig: AppConfig;
168173
let createInstallationSpy: SinonStub<
169174
[AppConfig, InProgressInstallationEntry],
170175
Promise<RegisteredInstallationEntry>
@@ -175,6 +180,9 @@ describe('getAuthToken', () => {
175180
>;
176181

177182
beforeEach(() => {
183+
app = getFakeApp();
184+
appConfig = extractAppConfig(app);
185+
178186
createInstallationSpy = stub(api, 'createInstallation').callsFake(
179187
async (_, installationEntry) => {
180188
await sleep(50); // Request would take some time
@@ -216,7 +224,9 @@ describe('getAuthToken', () => {
216224
describe('basic functionality', () => {
217225
for (const [title, setup] of setupInstallationEntryMap.entries()) {
218226
describe(`when ${title} in the DB`, () => {
219-
beforeEach(setup);
227+
beforeEach(() => {
228+
setup(appConfig);
229+
});
220230

221231
it('resolves with an auth token', async () => {
222232
const token = await getAuthToken(app);
@@ -226,7 +236,7 @@ describe('getAuthToken', () => {
226236
it('saves the token in the DB', async () => {
227237
const token = await getAuthToken(app);
228238
const installationEntry = await get<RegisteredInstallationEntry>(
229-
app.options.appId
239+
appConfig
230240
);
231241
expect(installationEntry).not.to.be.undefined;
232242
expect(installationEntry!.registrationStatus).to.equal(
@@ -281,7 +291,7 @@ describe('getAuthToken', () => {
281291
requestStatus: RequestStatus.NOT_STARTED
282292
}
283293
};
284-
await set(app.options.appId, installationEntry);
294+
await set(appConfig, installationEntry);
285295
});
286296

287297
it('gets the token by calling generateAuthToken', async () => {
@@ -314,7 +324,7 @@ describe('getAuthToken', () => {
314324
});
315325

316326
await expect(getAuthToken(app)).to.eventually.be.rejected;
317-
await expect(get(app.options.appId)).to.eventually.be.undefined;
327+
await expect(get(appConfig)).to.eventually.be.undefined;
318328
});
319329

320330
it('removes the FID from the DB if the server returns a 404 response', async () => {
@@ -328,7 +338,7 @@ describe('getAuthToken', () => {
328338
});
329339

330340
await expect(getAuthToken(app)).to.eventually.be.rejected;
331-
await expect(get(app.options.appId)).to.eventually.be.undefined;
341+
await expect(get(appConfig)).to.eventually.be.undefined;
332342
});
333343

334344
it('does not remove the FID from the DB if the server returns any other response', async () => {
@@ -342,7 +352,7 @@ describe('getAuthToken', () => {
342352
});
343353

344354
await expect(getAuthToken(app)).to.eventually.be.rejected;
345-
await expect(get(app.options.appId)).to.eventually.deep.equal(
355+
await expect(get(appConfig)).to.eventually.deep.equal(
346356
installationEntry
347357
);
348358
});
@@ -362,7 +372,7 @@ describe('getAuthToken', () => {
362372
creationTime: Date.now()
363373
}
364374
};
365-
await set(app.options.appId, installationEntry);
375+
await set(appConfig, installationEntry);
366376
});
367377

368378
it('does not call any server APIs', async () => {
@@ -394,7 +404,7 @@ describe('getAuthToken', () => {
394404
creationTime: Date.now() - ONE_WEEK_MS + TOKEN_EXPIRATION_BUFFER + 10
395405
}
396406
};
397-
await set(app.options.appId, installationEntry);
407+
await set(appConfig, installationEntry);
398408
});
399409

400410
it('returns a different token after expiration', async () => {
@@ -424,7 +434,7 @@ describe('getAuthToken', () => {
424434
creationTime: Date.now() - 2 * ONE_WEEK_MS
425435
}
426436
};
427-
await set(app.options.appId, installationEntry);
437+
await set(appConfig, installationEntry);
428438
});
429439

430440
it('throws if the app is offline', async () => {

packages/installations/src/get-auth-token.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ async function completeInstallationRegistration(
6363
async function fetchAuthToken(appConfig: AppConfig): Promise<string> {
6464
let tokenPromise: Promise<CompletedAuthToken> | undefined;
6565
const entry = await update(
66-
appConfig.appId,
66+
appConfig,
6767
(oldEntry?: InstallationEntry): RegisteredInstallationEntry => {
6868
if (!isEntryRegistered(oldEntry)) {
6969
throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);
@@ -75,7 +75,7 @@ async function fetchAuthToken(appConfig: AppConfig): Promise<string> {
7575
return oldEntry;
7676
} else if (oldAuthToken.requestStatus === RequestStatus.IN_PROGRESS) {
7777
// There already is a token request in progress.
78-
tokenPromise = waitUntilAuthTokenRequest(appConfig.appId);
78+
tokenPromise = waitUntilAuthTokenRequest(appConfig);
7979
return oldEntry;
8080
} else {
8181
// No token or token expired.
@@ -100,18 +100,18 @@ async function fetchAuthToken(appConfig: AppConfig): Promise<string> {
100100
* Call only if FID is registered and Auth Token request is in progress.
101101
*/
102102
async function waitUntilAuthTokenRequest(
103-
appId: string
103+
appConfig: AppConfig
104104
): Promise<CompletedAuthToken> {
105105
// Unfortunately, there is no way of reliably observing when a value in
106106
// IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),
107107
// so we need to poll.
108108

109-
let entry = await updateAuthTokenRequest(appId);
109+
let entry = await updateAuthTokenRequest(appConfig);
110110
while (entry.authToken.requestStatus === RequestStatus.IN_PROGRESS) {
111111
// generateAuthToken still in progress.
112112
await sleep(100);
113113

114-
entry = await updateAuthTokenRequest(appId);
114+
entry = await updateAuthTokenRequest(appConfig);
115115
}
116116

117117
const authToken = entry.authToken;
@@ -131,10 +131,10 @@ async function waitUntilAuthTokenRequest(
131131
* Returns the updated InstallationEntry.
132132
*/
133133
function updateAuthTokenRequest(
134-
appId: string
134+
appConfig: AppConfig
135135
): Promise<RegisteredInstallationEntry> {
136136
return update(
137-
appId,
137+
appConfig,
138138
(oldEntry?: InstallationEntry): RegisteredInstallationEntry => {
139139
if (!isEntryRegistered(oldEntry)) {
140140
throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);
@@ -163,19 +163,19 @@ async function fetchAuthTokenFromServer(
163163
...installationEntry,
164164
authToken
165165
};
166-
await set(appConfig.appId, updatedInstallationEntry);
166+
await set(appConfig, updatedInstallationEntry);
167167
return authToken;
168168
} catch (e) {
169169
if (isServerError(e) && (e.serverCode === 401 || e.serverCode === 404)) {
170170
// Server returned a "FID not found" or a "Invalid authentication" error.
171171
// Generate a new ID next time.
172-
await remove(appConfig.appId);
172+
await remove(appConfig);
173173
} else {
174174
const updatedInstallationEntry: RegisteredInstallationEntry = {
175175
...installationEntry,
176176
authToken: { requestStatus: RequestStatus.NOT_STARTED }
177177
};
178-
await set(appConfig.appId, updatedInstallationEntry);
178+
await set(appConfig, updatedInstallationEntry);
179179
}
180180
throw e;
181181
}

0 commit comments

Comments
 (0)