Skip to content

Commit 412019c

Browse files
feat: create web server identity token (#52)
* feat: create and add web server token * feat: refactor. add dev server utils * feat: dev server utils test * chore: nit * feat: test. nit * feat: 256 bit * chore: update after code review * chore: hex * chore: base64. update todo comment * chore: use updated CryptoUtils * chore: use sf config * chore: nit * chore: remove unused files * chore: remove validation * chore: use default local config. update tests * chore: update after code review * Update src/shared/identityUtils.ts Co-authored-by: Abdulsattar Mohammed <[email protected]> * chore: update tests * chore: removing unnecessary eslint disable --------- Co-authored-by: Abdulsattar Mohammed <[email protected]>
1 parent fa4af8b commit 412019c

File tree

5 files changed

+144
-5
lines changed

5 files changed

+144
-5
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"@oclif/core": "^3.26.6",
1212
"@salesforce/core": "^7.3.9",
1313
"@salesforce/kit": "^3.1.2",
14-
"@salesforce/lwc-dev-mobile-core": "4.0.0-alpha.3",
14+
"@salesforce/lwc-dev-mobile-core": "4.0.0-alpha.4",
1515
"@salesforce/sf-plugins-core": "^9.1.1",
1616
"@inquirer/select": "^2.3.5",
1717
"chalk": "^5.3.0",
@@ -58,6 +58,7 @@
5858
"oclif": {
5959
"commands": "./lib/commands",
6060
"bin": "sf",
61+
"configMeta": "./lib/configMeta",
6162
"topicSeparator": " ",
6263
"devPlugins": [
6364
"@oclif/plugin-help",

src/configMeta.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2024, salesforce.com, inc.
3+
* All rights reserved.
4+
* Licensed under the BSD 3-Clause license.
5+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
8+
import type { ConfigPropertyMeta } from '@salesforce/core';
9+
10+
export const enum ConfigVars {
11+
/**
12+
* The Base64-encoded identity token of the local web server, used to
13+
* validate the web server's identity to the hmr-client.
14+
*/
15+
LOCAL_WEB_SERVER_IDENTITY_TOKEN = 'local-web-server-identity-token',
16+
}
17+
18+
export default [
19+
{
20+
key: ConfigVars.LOCAL_WEB_SERVER_IDENTITY_TOKEN,
21+
description: 'The Base64-encoded identity token of the local web server',
22+
hidden: true,
23+
encrypted: true,
24+
},
25+
] as ConfigPropertyMeta[];

src/shared/identityUtils.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2024, salesforce.com, inc.
3+
* All rights reserved.
4+
* Licensed under the BSD 3-Clause license.
5+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
8+
import { CryptoUtils } from '@salesforce/lwc-dev-mobile-core';
9+
import { Config, ConfigAggregator } from '@salesforce/core';
10+
import configMeta, { ConfigVars } from './../configMeta.js';
11+
12+
export class IdentityUtils {
13+
public static async getOrCreateIdentityToken(): Promise<string> {
14+
let token = await this.getIdentityToken();
15+
if (!token) {
16+
token = CryptoUtils.generateIdentityToken();
17+
await this.writeIdentityToken(token);
18+
}
19+
return token;
20+
}
21+
22+
public static async getIdentityToken(): Promise<string | undefined> {
23+
const config = await ConfigAggregator.create({ customConfigMeta: configMeta });
24+
// Need to reload to make sure the values read are decrypted
25+
await config.reload();
26+
const identityToken = config.getPropertyValue(ConfigVars.LOCAL_WEB_SERVER_IDENTITY_TOKEN);
27+
28+
return identityToken as string;
29+
}
30+
31+
public static async writeIdentityToken(token: string): Promise<void> {
32+
const config = await Config.create({ isGlobal: false });
33+
Config.addAllowedProperties(configMeta);
34+
config.set(ConfigVars.LOCAL_WEB_SERVER_IDENTITY_TOKEN, token);
35+
await config.write();
36+
}
37+
}

test/shared/identityUtils.test.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright (c) 2024, salesforce.com, inc.
3+
* All rights reserved.
4+
* Licensed under the BSD 3-Clause license.
5+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
8+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
9+
/* eslint-disable @typescript-eslint/no-unsafe-call */
10+
11+
import { expect } from 'chai';
12+
import { Config, ConfigAggregator } from '@salesforce/core';
13+
import { TestContext } from '@salesforce/core/testSetup';
14+
import { CryptoUtils } from '@salesforce/lwc-dev-mobile-core';
15+
import { IdentityUtils } from '../../src/shared/identityUtils.js';
16+
import { ConfigVars } from '../../src/configMeta.js';
17+
18+
describe('identityUtils', () => {
19+
const $$ = new TestContext();
20+
21+
afterEach(() => {
22+
$$.restore();
23+
});
24+
25+
it('getOrCreateIdentityToken resolves if token is found', async () => {
26+
const fakeIdentityToken = 'fake identity token';
27+
$$.SANDBOX.stub(IdentityUtils, 'getIdentityToken').resolves(fakeIdentityToken);
28+
29+
const resolved = await IdentityUtils.getOrCreateIdentityToken();
30+
expect(resolved).to.equal(fakeIdentityToken);
31+
});
32+
33+
it('getOrCreateIdentityToken resolves and writeIdentityToken is called when there is no token', async () => {
34+
const fakeIdentityToken = 'fake identity token';
35+
$$.SANDBOX.stub(IdentityUtils, 'getIdentityToken').resolves(undefined);
36+
$$.SANDBOX.stub(CryptoUtils, 'generateIdentityToken').resolves(fakeIdentityToken);
37+
const writeIdentityTokenStub = $$.SANDBOX.stub(IdentityUtils, 'writeIdentityToken').resolves();
38+
39+
const resolved = await IdentityUtils.getOrCreateIdentityToken();
40+
expect(resolved).to.equal(fakeIdentityToken);
41+
expect(writeIdentityTokenStub.calledOnce).to.be.true;
42+
});
43+
44+
it('getIdentityToken resolves to undefined when identity token is not available', async () => {
45+
$$.SANDBOX.stub(ConfigAggregator, 'create').resolves(ConfigAggregator.prototype);
46+
$$.SANDBOX.stub(ConfigAggregator.prototype, 'reload').resolves();
47+
$$.SANDBOX.stub(ConfigAggregator.prototype, 'getPropertyValue').returns(undefined);
48+
const resolved = await IdentityUtils.getIdentityToken();
49+
50+
expect(resolved).to.equal(undefined);
51+
});
52+
53+
it('getIdentityToken resolves to a string when identity token is available', async () => {
54+
const fakeIdentityToken = 'fake identity token';
55+
$$.SANDBOX.stub(ConfigAggregator, 'create').resolves(ConfigAggregator.prototype);
56+
$$.SANDBOX.stub(ConfigAggregator.prototype, 'reload').resolves();
57+
$$.SANDBOX.stub(ConfigAggregator.prototype, 'getPropertyValue').returns(fakeIdentityToken);
58+
59+
const resolved = await IdentityUtils.getIdentityToken();
60+
expect(resolved).to.equal(fakeIdentityToken);
61+
});
62+
63+
it('writeIdentityToken resolves', async () => {
64+
const fakeIdentityToken = 'fake identity token';
65+
$$.SANDBOX.stub(Config, 'create').withArgs($$.SANDBOX.match.any).resolves(Config.prototype);
66+
$$.SANDBOX.stub(Config, 'addAllowedProperties').withArgs($$.SANDBOX.match.any);
67+
$$.SANDBOX.stub(Config.prototype, 'set').withArgs(
68+
ConfigVars.LOCAL_WEB_SERVER_IDENTITY_TOKEN,
69+
$$.SANDBOX.match.string
70+
);
71+
$$.SANDBOX.stub(Config.prototype, 'write').resolves();
72+
73+
const resolved = await IdentityUtils.writeIdentityToken(fakeIdentityToken);
74+
expect(resolved).to.equal(undefined);
75+
});
76+
});

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4304,10 +4304,10 @@
43044304
"@salesforce/ts-types" "^2.0.9"
43054305
tslib "^2.6.3"
43064306

4307-
"@salesforce/[email protected].3":
4308-
version "4.0.0-alpha.3"
4309-
resolved "https://registry.yarnpkg.com/@salesforce/lwc-dev-mobile-core/-/lwc-dev-mobile-core-4.0.0-alpha.3.tgz#7485689c78e97b53ba88ce714db11bbeacfde192"
4310-
integrity sha512-7o7n6tuTshqwmfym2vy89IvMB8rKUcqDL7mg/nQ77wP4OxAjtj+mQzamcLz1nQU7QI4529RbkBvXe/2R0zbXBA==
4307+
"@salesforce/[email protected].4":
4308+
version "4.0.0-alpha.4"
4309+
resolved "https://registry.yarnpkg.com/@salesforce/lwc-dev-mobile-core/-/lwc-dev-mobile-core-4.0.0-alpha.4.tgz#5e020cb3222f2603a01248359d43b3d6ca4062e3"
4310+
integrity sha512-gNEQQr4QIIdXgGmSr6820Y2/HR7YqwxBjf0Z/PKr/iNoQ24Agc1QGMfUysc5H7/Bmx69GPF9wq7ahbNjSvB+Kg==
43114311
dependencies:
43124312
"@oclif/core" "^3.26.6"
43134313
"@salesforce/core" "^7.3.6"

0 commit comments

Comments
 (0)