Skip to content

Commit

Permalink
feat: add validation function for authorizationArgs (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnStarich authored Mar 28, 2020
1 parent 3507bf0 commit e897b04
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import * as path from 'path';

import { spawn } from './spawn';
import { withTempDir, makeSecret, parseNotarizationInfo } from './helpers';
import { validateAuthorizationArgs, isPasswordCredentials } from './validate-args';

const d = debug('electron-notarize');

export { validateAuthorizationArgs } from './validate-args';

export interface NotarizePasswordCredentials {
appleId: string;
appleIdPassword: string;
Expand Down Expand Up @@ -36,8 +39,9 @@ export type NotarizeWaitOptions = NotarizeResult & NotarizeCredentials;
export type NotarizeStapleOptions = Pick<NotarizeAppOptions, 'appPath'>;
export type NotarizeOptions = NotarizeStartOptions;

function authorizationArgs(opts: NotarizeCredentials): string[] {
if ('appleId' in opts) {
function authorizationArgs(rawOpts: NotarizeCredentials): string[] {
const opts = validateAuthorizationArgs(rawOpts);
if (isPasswordCredentials(opts)) {
return ['-u', makeSecret(opts.appleId), '-p', makeSecret(opts.appleIdPassword)];
} else {
return [
Expand Down
52 changes: 52 additions & 0 deletions src/validate-args.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {
NotarizeApiKeyCredentials,
NotarizeCredentials,
NotarizePasswordCredentials,
} from './index';

export function isPasswordCredentials(
opts: NotarizeCredentials,
): opts is NotarizePasswordCredentials {
const creds = opts as NotarizePasswordCredentials;
return creds.appleId !== undefined || creds.appleIdPassword !== undefined;
}

export function isApiKeyCredentials(opts: NotarizeCredentials): opts is NotarizeApiKeyCredentials {
const creds = opts as NotarizeApiKeyCredentials;
return creds.appleApiKey !== undefined || creds.appleApiIssuer !== undefined;
}

export function validateAuthorizationArgs(opts: NotarizeCredentials): NotarizeCredentials {
const isPassword = isPasswordCredentials(opts);
const isApiKey = isApiKeyCredentials(opts);
if (isPassword && isApiKey) {
throw new Error('Cannot use both password credentials and API key credentials at once');
}
if (isPassword) {
const passwordCreds = opts as NotarizePasswordCredentials;
if (!passwordCreds.appleId) {
throw new Error(
'The appleId property is required when using notarization with appleIdPassword',
);
} else if (!passwordCreds.appleIdPassword) {
throw new Error(
'The appleIdPassword property is required when using notarization with appleId',
);
}
return passwordCreds;
}
if (isApiKey) {
const apiKeyCreds = opts as NotarizeApiKeyCredentials;
if (!apiKeyCreds.appleApiKey) {
throw new Error(
'The appleApiKey property is required when using notarization with appleApiIssuer',
);
} else if (!apiKeyCreds.appleApiIssuer) {
throw new Error(
'The appleApiIssuer property is required when using notarization with appleApiKey',
);
}
return apiKeyCreds;
}
throw new Error('No authentication properties provided (e.g. appleId, appleApiKey)');
}
73 changes: 73 additions & 0 deletions test/validate-args.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {
NotarizeApiKeyCredentials,
NotarizeCredentials,
NotarizePasswordCredentials,
} from '../src/index';
import { validateAuthorizationArgs } from '../src/validate-args';

describe('index', () => {
describe('validateAuthorizationArgs', () => {
test('password credentials provided', () => {
const opts = {
'appleId': 'fakeId',
'appleIdPassword': 'fakePassword',
} as NotarizePasswordCredentials;
expect(validateAuthorizationArgs(opts)).toEqual(opts);
});

test('API key credentials provided', () => {
const opts = {
'appleApiKey': 'fakeApiKey',
'appleApiIssuer': 'fakeApiIssuer',
} as NotarizeApiKeyCredentials;
expect(validateAuthorizationArgs(opts)).toEqual(opts);
});

test('credentials are required', () => {
const opts = {} as NotarizeCredentials;
expect(() => validateAuthorizationArgs(opts))
.toThrowError(new Error('No authentication properties provided (e.g. appleId, appleApiKey)'));
});

test('only one kind of credentials', () => {
const opts = {
'appleId': 'fakeId',
'appleApiKey': 'fakeApiKey',
} as any;
expect(() => validateAuthorizationArgs(opts))
.toThrowError(new Error('Cannot use both password credentials and API key credentials at once'));
});

test('missing appleId', () => {
const opts = {
'appleIdPassword': 'fakePassword',
} as any;
expect(() => validateAuthorizationArgs(opts))
.toThrowError(new Error('The appleId property is required when using notarization with appleIdPassword'));
});

test('missing appleIdPassword', () => {
const opts = {
'appleId': 'fakeId',
} as any;
expect(() => validateAuthorizationArgs(opts))
.toThrowError(new Error('The appleIdPassword property is required when using notarization with appleId'));
});

test('missing appleApiKey', () => {
const opts = {
'appleApiIssuer': 'fakeApiIssuer',
} as any;
expect(() => validateAuthorizationArgs(opts))
.toThrowError(new Error('The appleApiKey property is required when using notarization with appleApiIssuer'));
});

test('missing appleApiIssuer', () => {
const opts = {
'appleApiKey': 'fakeApiKey',
} as any;
expect(() => validateAuthorizationArgs(opts))
.toThrowError(new Error('The appleApiIssuer property is required when using notarization with appleApiKey'));
});
});
});

0 comments on commit e897b04

Please sign in to comment.