Skip to content

Commit

Permalink
Merge pull request #219 from forcedotcom/develop
Browse files Browse the repository at this point in the history
release: merge develop to master
  • Loading branch information
amphro authored Apr 23, 2020
2 parents f5ebc33 + ec5a10c commit 0afeec8
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 4 deletions.
39 changes: 35 additions & 4 deletions src/authInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,35 @@ export class AuthInfo extends AsyncCreatable<AuthInfo.Options> {
return false;
}

/**
* Parse a sfdx auth url, usually obtained by `authInfo.getSfdxAuthUrl`.
*
* @example
* ```
* await AuthInfo.create(AuthInfo.parseSfdxAuthUrl(sfdxAuthUrl));
* ```
* @param sfdxAuthUrl
*/
public static parseSfdxAuthUrl(sfdxAuthUrl: string) {
const match = sfdxAuthUrl.match(
/^force:\/\/([a-zA-Z0-9._-]+):([a-zA-Z0-9._-]*):([a-zA-Z0-9._-]+)@([a-zA-Z0-9._-]+)/
);

if (!match) {
throw new SfdxError(
'Invalid sfdx auth url. Must be in the format `force://<clientId>:<clientSecret>:<refreshToken>@<loginUrl>`. The instanceUrl must not have the protocol set.',
'INVALID_SFDX_AUTH_URL'
);
}
const [, clientId, clientSecret, refreshToken, loginUrl] = match;
return {
clientId,
clientSecret,
refreshToken,
loginUrl: `https://${loginUrl}`
};
}

// The regular expression that filters files stored in $HOME/.sfdx
private static authFilenameFilterRegEx: RegExp = /^[^.][^@]*@[^.]+(\.[^.\s]+)+\.json$/;

Expand Down Expand Up @@ -690,14 +719,16 @@ export class AuthInfo extends AsyncCreatable<AuthInfo.Options> {
// Update the auth fields WITH encryption
this.update(authConfig);
} else {
const username = ensure(this.getUsername());
authConfig = await this.loadAuthFromConfig(username);
authConfig = await this.loadAuthFromConfig(ensure(this.getUsername()));
// Update the auth fields WITHOUT encryption (already encrypted)
this.update(authConfig, false);
}

// Cache the fields by username (fields are encrypted)
AuthInfo.cache.set(ensure(this.getUsername()), this.fields);
const username = this.getUsername();
if (username) {
// Cache the fields by username (fields are encrypted)
AuthInfo.cache.set(username, this.fields);
}

return this;
}
Expand Down
66 changes: 66 additions & 0 deletions test/unit/authInfoTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,31 @@ describe('AuthInfo', () => {
});
});

it('should not cache when no username is supplied', async () => {
const cacheSize = AuthInfo['cache'].size;

const authResponse = {
access_token: testMetadata.accessToken,
instance_url: testMetadata.instanceUrl,
id: '00DAuthInfoTest_orgId/005AuthInfoTest_userId',
refresh_token: testMetadata.refreshToken
};

// Stub the http requests (OAuth2.requestToken() and the request for the username)
_postParmsStub.returns(Promise.resolve(authResponse));

// Create the AuthInfo instance with no username
await AuthInfo.create({
oauth2Options: {
refreshToken: testMetadata.refreshToken,
loginUrl: testMetadata.loginUrl,
clientId: testMetadata.clientId
}
});

expect(AuthInfo['cache'].size).to.equal(cacheSize);
});

it('should return a JWT AuthInfo instance when passed a username from an auth file', async () => {
const username = 'authInfoTest_username_jwt-NOT-CACHED';

Expand Down Expand Up @@ -1547,4 +1572,45 @@ describe('AuthInfo', () => {
}
});
});

describe('parseSfdxAuthUrl()', () => {
it('should parse the correct url with no client secret', () => {
const options = AuthInfo.parseSfdxAuthUrl(
'force://PlatformCLI::5Aep861_OKMvio5gy8xCNsXxybPdupY9fVEZyeVOvb4kpOZx5Z1QLB7k7n5flEqEWKcwUQEX1I.O5DCFwjlYUB.@test.my.salesforce.com'
);

expect(options.refreshToken).to.equal(
'5Aep861_OKMvio5gy8xCNsXxybPdupY9fVEZyeVOvb4kpOZx5Z1QLB7k7n5flEqEWKcwUQEX1I.O5DCFwjlYUB.'
);
expect(options.clientId).to.equal('PlatformCLI');
expect(options.clientSecret).to.equal('');
expect(options.loginUrl).to.equal('https://test.my.salesforce.com');
});

it('should parse the correct url with client secret', () => {
const options = AuthInfo.parseSfdxAuthUrl(
'force://3MVG9SemV5D80oBfPBCgboxuJ9cOMLWNM1DDOZ8zgvJGsz13H3J66coUBCFF3N0zEgLYijlkqeWk4ot_Q2.4o:438437816653243682:5Aep861_OKMvio5gy8xCNsXxybPdupY9fVEZyeVOvb4kpOZx5Z1QLB7k7n5flEqEWKcwUQEX1I.O5DCFwjlYUB.@test.my.salesforce.com'
);

expect(options.refreshToken).to.equal(
'5Aep861_OKMvio5gy8xCNsXxybPdupY9fVEZyeVOvb4kpOZx5Z1QLB7k7n5flEqEWKcwUQEX1I.O5DCFwjlYUB.'
);
expect(options.clientId).to.equal(
'3MVG9SemV5D80oBfPBCgboxuJ9cOMLWNM1DDOZ8zgvJGsz13H3J66coUBCFF3N0zEgLYijlkqeWk4ot_Q2.4o'
);
expect(options.clientSecret).to.equal('438437816653243682');
expect(options.loginUrl).to.equal('https://test.my.salesforce.com');
});

it('should throw with incorrect url', () => {
try {
AuthInfo.parseSfdxAuthUrl(
'PlatformCLI::5Aep861_OKMvio5gy8xCNsXxybPdupY9fVEZyeVOvb4kpOZx5Z1QLB7k7n5flEqEWKcwUQEX1I.O5DCFwjlYUB.@test.my.salesforce.com'
);
assert.fail();
} catch (e) {
expect(e.name).to.equal('INVALID_SFDX_AUTH_URL');
}
});
});
});

0 comments on commit 0afeec8

Please sign in to comment.