Skip to content

Commit 75b8c36

Browse files
committed
test
1 parent a9008b8 commit 75b8c36

File tree

3 files changed

+103
-50
lines changed

3 files changed

+103
-50
lines changed

lib/utils.js

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
3333
};
3434
Object.defineProperty(exports, "__esModule", { value: true });
3535
exports.Utils = void 0;
36+
exports.parseInput = parseInput;
3637
const core = __importStar(require("@actions/core"));
3738
const exec_1 = require("@actions/exec");
3839
const http_client_1 = require("@actions/http-client");
@@ -315,7 +316,7 @@ class Utils {
315316
if (!!oidcProviderName && !!oidcTokenId) {
316317
core.info('calling EOT ! ');
317318
let output = yield (0, exec_1.getExecOutput)('jf', ['eot', oidcProviderName, oidcTokenId, '--url', url, '--oidc-audience', oidcAudience], { silent: true, ignoreReturnCode: true });
318-
const { accessToken, username } = Utils.extractValues(output.stdout);
319+
const { accessToken, username } = parseInput(output.stdout);
319320
// Sets the OIDC token as access token to be used in config.
320321
core.info('setting as secret');
321322
core.setSecret('oidc-token');
@@ -335,17 +336,6 @@ class Utils {
335336
return configCmd;
336337
});
337338
}
338-
static extractValues(input) {
339-
const regex = /AccessToken:\s*([\w-]+)\s*Username:\s*([\w-]+)/;
340-
const match = regex.exec(input);
341-
if (!match) {
342-
throw new Error('Failed to extract values. Input format is invalid.');
343-
}
344-
return {
345-
accessToken: match[1],
346-
username: match[2],
347-
};
348-
}
349339
/**
350340
* Get server ID for JFrog CLI configuration. Save the server ID in the servers env var if it doesn't already exist.
351341
*/
@@ -1041,3 +1031,28 @@ Utils.METRIC_PARAM_KEY = 'm';
10411031
Utils.METRIC_PARAM_VALUE = '1';
10421032
Utils.MIN_CLI_OIDC_VERSION = '2.75.0';
10431033
Utils.DEFAULT_OIDC_AUDIENCE = 'jfrog-github';
1034+
function parseInput(input) {
1035+
try {
1036+
// Attempt to parse as JSON
1037+
const parsed = JSON.parse(input);
1038+
if (parsed.AccessToken && parsed.Username) {
1039+
return {
1040+
accessToken: parsed.AccessToken,
1041+
username: parsed.Username,
1042+
};
1043+
}
1044+
throw new Error('JSON does not contain required fields.');
1045+
}
1046+
catch (_a) {
1047+
// Fallback to regex extraction
1048+
const regex = /AccessToken:\s*(\S+)\s*Username:\s*(\S+)/;
1049+
const match = regex.exec(input);
1050+
if (!match) {
1051+
throw new Error('Failed to extract values. Input format is invalid.');
1052+
}
1053+
return {
1054+
accessToken: match[1],
1055+
username: match[2],
1056+
};
1057+
}
1058+
}

src/utils.ts

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ export class Utils {
389389
['eot', oidcProviderName, oidcTokenId, '--url', url, '--oidc-audience', oidcAudience],
390390
{ silent: true, ignoreReturnCode: true },
391391
);
392-
const { accessToken, username }: { accessToken: string; username: string } = Utils.extractValues(output.stdout);
392+
const { accessToken, username }: { accessToken: string; username: string } = parseInput(output.stdout);
393393
// Sets the OIDC token as access token to be used in config.
394394
core.info('setting as secret');
395395
core.setSecret('oidc-token');
@@ -409,19 +409,6 @@ export class Utils {
409409
return configCmd;
410410
}
411411

412-
private static extractValues(input: string): { accessToken: string; username: string } {
413-
const regex: RegExp = /AccessToken:\s*([\w-]+)\s*Username:\s*([\w-]+)/;
414-
const match: RegExpMatchArray | null = regex.exec(input);
415-
416-
if (!match) {
417-
throw new Error('Failed to extract values. Input format is invalid.');
418-
}
419-
420-
return {
421-
accessToken: match[1],
422-
username: match[2],
423-
};
424-
}
425412
/**
426413
* Get server ID for JFrog CLI configuration. Save the server ID in the servers env var if it doesn't already exist.
427414
*/
@@ -1064,6 +1051,33 @@ export class Utils {
10641051
}
10651052
}
10661053

1054+
export function parseInput(input: string): { accessToken: string; username: string } {
1055+
try {
1056+
// Attempt to parse as JSON
1057+
const parsed: { AccessToken?: string; Username?: string } = JSON.parse(input);
1058+
if (parsed.AccessToken && parsed.Username) {
1059+
return {
1060+
accessToken: parsed.AccessToken,
1061+
username: parsed.Username,
1062+
};
1063+
}
1064+
throw new Error('JSON does not contain required fields.');
1065+
} catch {
1066+
// Fallback to regex extraction
1067+
const regex: RegExp = /AccessToken:\s*(\S+)\s*Username:\s*(\S+)/;
1068+
const match: RegExpMatchArray | null = regex.exec(input);
1069+
1070+
if (!match) {
1071+
throw new Error('Failed to extract values. Input format is invalid.');
1072+
}
1073+
1074+
return {
1075+
accessToken: match[1],
1076+
username: match[2],
1077+
};
1078+
}
1079+
}
1080+
10671081
export interface DownloadDetails {
10681082
artifactoryUrl: string;
10691083
repository: string;

test/main.spec.ts

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as os from 'os';
22
import * as core from '@actions/core';
33

4-
import { DownloadDetails, JfrogCredentials, JWTTokenData, Utils } from '../src/utils';
4+
import { DownloadDetails, JfrogCredentials, JWTTokenData, parseInput, Utils } from '../src/utils';
55
import * as jsYaml from 'js-yaml';
66
import * as fs from 'fs';
77
import * as path from 'path';
@@ -122,22 +122,22 @@ describe('Collect JFrog Credentials from env vars exceptions', () => {
122122
});
123123
});
124124

125-
function testConfigCommand(expectedServerId: string) {
125+
async function testConfigCommand(expectedServerId: string) {
126126
// No url
127-
let configCommand: string[] | undefined = Utils.getSeparateEnvConfigArgs({} as JfrogCredentials);
127+
let configCommand: string[] | undefined = await Utils.getSeparateEnvConfigArgs({} as JfrogCredentials);
128128
expect(configCommand).toBe(undefined);
129129

130130
let jfrogCredentials: JfrogCredentials = {} as JfrogCredentials;
131131
jfrogCredentials.jfrogUrl = DEFAULT_CLI_URL;
132132

133133
// No credentials
134-
configCommand = Utils.getSeparateEnvConfigArgs(jfrogCredentials);
134+
configCommand = await Utils.getSeparateEnvConfigArgs(jfrogCredentials);
135135
expect(configCommand).toStrictEqual([expectedServerId, '--url', DEFAULT_CLI_URL, '--interactive=false', '--overwrite=true']);
136136

137137
// Basic authentication
138138
jfrogCredentials.username = 'user';
139139
jfrogCredentials.password = 'password';
140-
configCommand = Utils.getSeparateEnvConfigArgs(jfrogCredentials);
140+
configCommand = await Utils.getSeparateEnvConfigArgs(jfrogCredentials);
141141
expect(configCommand).toStrictEqual([
142142
expectedServerId,
143143
'--url',
@@ -154,7 +154,7 @@ function testConfigCommand(expectedServerId: string) {
154154
jfrogCredentials.username = '';
155155
jfrogCredentials.password = '';
156156
jfrogCredentials.accessToken = 'accessToken';
157-
configCommand = Utils.getSeparateEnvConfigArgs(jfrogCredentials);
157+
configCommand = await Utils.getSeparateEnvConfigArgs(jfrogCredentials);
158158
expect(configCommand).toStrictEqual([
159159
expectedServerId,
160160
'--url',
@@ -178,7 +178,7 @@ describe('JFrog CLI Configuration', () => {
178178
});
179179

180180
// Before setting a custom server ID, expect the default server ID to be used.
181-
testConfigCommand(Utils.getRunDefaultServerId());
181+
await testConfigCommand(Utils.getRunDefaultServerId());
182182

183183
// Expect the custom server ID to be used.
184184
let customServerId: string = 'custom-server-id';
@@ -188,7 +188,7 @@ describe('JFrog CLI Configuration', () => {
188188
}
189189
return ''; // Default return value for other arguments
190190
});
191-
testConfigCommand(customServerId);
191+
await testConfigCommand(customServerId);
192192

193193
// Expect the servers env var to include both servers.
194194
const servers: string[] = Utils.getConfiguredJFrogServers();
@@ -582,48 +582,48 @@ describe('getSeparateEnvConfigArgs', () => {
582582
jest.restoreAllMocks();
583583
});
584584

585-
it('should return undefined if URL is not set', () => {
585+
it('should return undefined if URL is not set', async () => {
586586
const creds: JfrogCredentials = {} as JfrogCredentials;
587-
expect(Utils.getSeparateEnvConfigArgs(creds)).toBeUndefined();
587+
expect(await Utils.getSeparateEnvConfigArgs(creds)).toBeUndefined();
588588
});
589589

590-
it('should use access token if provided', () => {
590+
it('should use access token if provided', async () => {
591591
const creds: JfrogCredentials = {
592592
jfrogUrl: 'https://example.jfrog.io',
593593
accessToken: 'abc',
594594
} as JfrogCredentials;
595-
const args: string[] | undefined = Utils.getSeparateEnvConfigArgs(creds);
595+
const args: string[] | undefined = await Utils.getSeparateEnvConfigArgs(creds);
596596
expect(args).toContain('--access-token');
597597
expect(args).toContain('abc');
598598
});
599599

600-
it('should use username and password if provided and access token is not', () => {
600+
it('should use username and password if provided and access token is not', async () => {
601601
const creds: JfrogCredentials = {
602602
jfrogUrl: 'https://example.jfrog.io',
603603
username: 'admin',
604604
password: '1234',
605605
} as JfrogCredentials;
606-
const args: string[] | undefined = Utils.getSeparateEnvConfigArgs(creds);
606+
const args: string[] | undefined = await Utils.getSeparateEnvConfigArgs(creds);
607607
expect(args).toContain('--user');
608608
expect(args).toContain('admin');
609609
expect(args).toContain('--password');
610610
expect(args).toContain('1234');
611611
});
612612

613-
it('should use OIDC provider if specified', () => {
613+
it('should use OIDC provider if specified', async () => {
614614
const creds: JfrogCredentials = {
615615
jfrogUrl: 'https://example.jfrog.io',
616616
oidcProviderName: 'setup-jfrog-cli',
617617
oidcTokenId: 'abc-123',
618618
oidcAudience: 'jfrog-github',
619619
} as JfrogCredentials;
620-
const args: string[] | undefined = Utils.getSeparateEnvConfigArgs(creds);
620+
const args: string[] | undefined = await Utils.getSeparateEnvConfigArgs(creds);
621621
expect(args).toContain('--oidc-provider-name=setup-jfrog-cli');
622622
expect(args).toContain('--oidc-provider-type=Github');
623623
expect(args).toContain('--oidc-token-id=abc-123');
624624
expect(args).toContain('--oidc-audience=jfrog-github');
625625
});
626-
it('should not include conflicting or duplicate arguments in the config command', () => {
626+
it('should not include conflicting or duplicate arguments in the config command', async () => {
627627
const jfrogCredentials: JfrogCredentials = {
628628
jfrogUrl: 'https://example.jfrog.io',
629629
username: 'test-user',
@@ -634,7 +634,7 @@ describe('getSeparateEnvConfigArgs', () => {
634634
oidcTokenId: '',
635635
};
636636

637-
const configArgs: string[] | undefined = Utils.getSeparateEnvConfigArgs(jfrogCredentials);
637+
const configArgs: string[] | undefined = await Utils.getSeparateEnvConfigArgs(jfrogCredentials);
638638

639639
// Ensure the command does not include conflicting or duplicate arguments
640640
const configString: string = configArgs?.join(' ') || '';
@@ -645,7 +645,7 @@ describe('getSeparateEnvConfigArgs', () => {
645645
expect(configString).toContain('--oidc-audience=jfrog-github');
646646
expect(configString).not.toContain('--access-token test-access-token --username test-user'); // Ensure no conflicting auth methods
647647
});
648-
it('Access Token Auth should be prioritized over basic auth', () => {
648+
it('Access Token Auth should be prioritized over basic auth', async () => {
649649
const jfrogCredentials: JfrogCredentials = {
650650
jfrogUrl: 'https://example.jfrog.io',
651651
username: 'test-user',
@@ -656,7 +656,7 @@ describe('getSeparateEnvConfigArgs', () => {
656656
oidcTokenId: '',
657657
};
658658

659-
const configArgs: string[] | undefined = Utils.getSeparateEnvConfigArgs(jfrogCredentials);
659+
const configArgs: string[] | undefined = await Utils.getSeparateEnvConfigArgs(jfrogCredentials);
660660

661661
// Ensure the command does not include conflicting or duplicate arguments
662662
const configString: string = configArgs?.join(' ') || '';
@@ -739,7 +739,7 @@ describe('handleOidcAuth', () => {
739739
const result: JfrogCredentials = await (Utils as any).handleOidcAuth(credentials);
740740
expect(result.accessToken).toBe('forced-manual-token');
741741
});
742-
it('should include OIDC flags only for supported versions', () => {
742+
it('should include OIDC flags only for supported versions', async () => {
743743
const creds: JfrogCredentials = {
744744
jfrogUrl: 'https://example.jfrog.io',
745745
oidcProviderName: 'setup-jfrog-cli',
@@ -752,14 +752,14 @@ describe('handleOidcAuth', () => {
752752
return '';
753753
});
754754

755-
const args: string[] | undefined = Utils.getSeparateEnvConfigArgs(creds);
755+
const args: string[] | undefined = await Utils.getSeparateEnvConfigArgs(creds);
756756
expect(args).toContain('--oidc-provider-name=setup-jfrog-cli');
757757
expect(args).toContain('--oidc-provider-type=Github');
758758
expect(args).toContain('--oidc-token-id=abc-123');
759759
expect(args).toContain('--oidc-audience=jfrog-github');
760760
});
761761

762-
it('should not include OIDC flags for unsupported versions', () => {
762+
it('should not include OIDC flags for unsupported versions', async () => {
763763
const creds: JfrogCredentials = {
764764
jfrogUrl: 'https://example.jfrog.io',
765765
oidcProviderName: 'setup-jfrog-cli',
@@ -772,10 +772,34 @@ describe('handleOidcAuth', () => {
772772
return '';
773773
});
774774

775-
const args: string[] | undefined = Utils.getSeparateEnvConfigArgs(creds);
775+
const args: string[] | undefined = await Utils.getSeparateEnvConfigArgs(creds);
776776
expect(args).not.toContain('--oidc-provider-name=setup-jfrog-cli');
777777
expect(args).not.toContain('--oidc-provider-type=Github');
778778
expect(args).not.toContain('--oidc-token-id=abc-123');
779779
expect(args).not.toContain('--oidc-audience=jfrog-github');
780780
});
781781
});
782+
783+
describe('parseInput', () => {
784+
it('should parse valid JSON input', () => {
785+
const input: string = '{"AccessToken": "abc123", "Username": "user456"}';
786+
const result: { accessToken: string; username: string } = parseInput(input);
787+
expect(result).toEqual({ accessToken: 'abc123', username: 'user456' });
788+
});
789+
790+
it('should fallback to regex for non-JSON input', () => {
791+
const input: string = '{ AccessToken: abc123 Username: user456 }';
792+
const result: { accessToken: string; username: string } = parseInput(input);
793+
expect(result).toEqual({ accessToken: 'abc123', username: 'user456' });
794+
});
795+
796+
it('should throw an error for invalid input format', () => {
797+
const input: string = 'Invalid input';
798+
expect(() => parseInput(input)).toThrow('Failed to extract values. Input format is invalid.');
799+
});
800+
801+
it('should throw an error for JSON without required fields', () => {
802+
const input: string = '{"key": "value"}';
803+
expect(() => parseInput(input)).toThrow('Failed to extract values. Input format is invalid.');
804+
});
805+
});

0 commit comments

Comments
 (0)