Skip to content

Commit effc9e6

Browse files
committed
enforced org rules
1 parent bc6c0ab commit effc9e6

File tree

5 files changed

+61
-55
lines changed

5 files changed

+61
-55
lines changed

lib/commands/login/index.js

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -70,45 +70,42 @@ export const login = {
7070
}
7171

7272
/** @type {prompts.Choice[]} */
73-
const orgChoices = Object.values(settings.organizations)
73+
const enforcedChoices = Object.values(settings.organizations)
74+
.filter(org => org.plan.tier === 'enterprise')
7475
.map(org => ({
7576
title: org.name,
76-
description: `${org.plan.tier} tier`,
77-
selected: true,
7877
value: org.id
7978
}))
8079

81-
/** @type {string[]} */
82-
let orgIDs = []
80+
/** @type {string | null} */
81+
let enforcedOrg = null
8382

84-
if (orgChoices.length > 1) {
85-
const { ids } = await prompts({
86-
type: 'multiselect',
87-
name: 'ids',
88-
instructions: '',
89-
hint: '\n Use ←/→/space to select and deselect, then hit enter to submit\n',
90-
message: 'Which organizations\' policies would you like Socket to enforce?',
91-
choices: orgChoices,
92-
min: 0,
83+
if (enforcedChoices.length > 1) {
84+
const { id } = await prompts({
85+
type: 'select',
86+
name: 'id',
87+
hint: '\n Pick "None" if this is a personal device',
88+
message: 'Which organization\'s policies should Socket globally enforce?',
89+
choices: enforcedChoices.concat({
90+
title: 'None',
91+
value: null
92+
}),
9393
onState: promptAbortHandler
9494
})
95-
orgIDs = ids
96-
} else if (orgChoices.length) {
95+
enforcedOrg = id
96+
} else if (enforcedChoices.length) {
9797
const { confirmOrg } = await prompts({
9898
type: 'confirm',
9999
name: 'confirmOrg',
100-
message: `Enforce organization policies for ${orgChoices[0]?.title}?`,
100+
message: `Should Socket globally enforce ${enforcedChoices[0]?.title}'s security policies?`,
101101
initial: true,
102102
onState: promptAbortHandler
103103
})
104104
if (confirmOrg) {
105-
orgIDs = [orgChoices[0]?.value]
105+
enforcedOrg = enforcedChoices[0]?.value
106106
}
107107
}
108-
updateSetting('orgs', orgIDs.map(id => ({
109-
id,
110-
issueRules: settings.organizations[id].issueRules
111-
})))
108+
updateSetting('enforcedOrg', enforcedOrg)
112109
const oldKey = getSetting('apiKey')
113110
updateSetting('apiKey', apiKey)
114111
spinner.succeed(`API credentials ${oldKey ? 'updated' : 'set'}`)

lib/commands/logout/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const logout = {
2727
if (cli.input.length) cli.showHelp()
2828

2929
updateSetting('apiKey', null)
30-
updateSetting('orgs', null)
30+
updateSetting('enforcedOrg', null)
3131
ora('Successfully logged out').succeed()
3232
}
3333
}

lib/shadow/link.cjs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,34 @@ const path = require('path')
55
const which = require('which')
66

77
if (process.platform === 'win32') {
8-
console.error('Socket npm and socket npx wrapper Windows suppport is limited to WSL at this time.')
8+
console.error('Socket dependency manager Windows suppport is limited to WSL at this time.')
99
process.exit(1)
1010
}
1111

1212
/**
1313
* @param {string} realDirname path to shadow/bin
1414
* @param {'npm' | 'npx'} binname
15-
* @returns {string} path to npm provided cli / npx bin
15+
* @returns {string} path to original bin
1616
*/
1717
function installLinks (realDirname, binname) {
18-
const realNpmShadowBinDir = realDirname
19-
// find npm being shadowed by this process
20-
const npms = which.sync(binname, {
18+
const realShadowBinDir = realDirname
19+
// find package manager being shadowed by this process
20+
const bins = which.sync(binname, {
2121
all: true
2222
})
2323
let shadowIndex = -1
24-
const npmpath = npms.find((npmPath, i) => {
25-
const isShadow = realpathSync(path.dirname(npmPath)) === realNpmShadowBinDir
24+
const binpath = bins.find((binPath, i) => {
25+
const isShadow = realpathSync(path.dirname(binPath)) === realShadowBinDir
2626
if (isShadow) {
2727
shadowIndex = i
2828
}
2929
return !isShadow
3030
})
31-
if (npmpath && process.platform === 'win32') {
32-
return npmpath
31+
if (binpath && process.platform === 'win32') {
32+
return binpath
3333
}
34-
if (!npmpath) {
35-
console.error('Socket unable to locate npm ensure it is available in the PATH environment variable')
34+
if (!binpath) {
35+
console.error(`Socket unable to locate ${binname}; ensure it is available in the PATH environment variable`)
3636
process.exit(127)
3737
}
3838
if (shadowIndex === -1) {

lib/shadow/npm-injection.cjs

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,33 +36,42 @@ try {
3636

3737
const pubTokenPromise = sdkPromise.then(({ getDefaultKey, FREE_API_KEY }) => getDefaultKey() || FREE_API_KEY)
3838
const apiKeySettingsPromise = sdkPromise.then(async ({ setupSdk }) => {
39-
const sdk = await setupSdk();
39+
const sdk = await setupSdk()
4040
const result = await sdk.getSettings()
4141
if (!result.success) throw new Error('failed to fetch API key settings')
42-
return result.data;
42+
return result.data
4343
})
4444

4545
/** @type {Promise<{ id: string, issueRules: import('../utils/settings.js').IssueRules }[]>} */
4646
const orgSettingsPromise = settingsPromise.then(async ({ getSetting, updateSetting }) => {
47-
const orgs = getSetting('orgs') || [];
48-
if (!orgs.length) return [];
49-
47+
const enforcedOrg = getSetting('enforcedOrg')
5048
const settings = await apiKeySettingsPromise
51-
const newOrgs = orgs.filter(org => settings.organizations[org.id])
52-
.map(org => {
53-
const curOrg = settings.organizations[org.id];
54-
return {
55-
id: org.id,
56-
issueRules: curOrg.plan.tier === 'enterprise' || curOrg.plan.tier === 'team'
57-
? curOrg.issueRules
58-
: org.issueRules
59-
}
60-
})
49+
const enforcedRules = enforcedOrg && settings.organizations[enforcedOrg] || {}
6150

62-
updateSetting('orgs', newOrgs);
51+
/**
52+
* @param {import('../utils/settings.js').IssueRules[string]} rule
53+
* @returns {number}
54+
*/
55+
const ruleStrength = (rule) => {
56+
if (typeof rule === 'boolean') return rule ? 3 : 1
57+
switch (rule.action) {
58+
case 'error': return 3
59+
case 'warn': return 2
60+
case 'ignore': return 1
61+
case 'defer': return 0
62+
}
63+
}
6364

64-
return newOrgs.map(({ id, issueRules }) => {
65-
const defaultedRules = { ...issueRules };
65+
return Object.values(settings.organizations).map(({ id, issueRules }) => {
66+
const defaultedRules = { ...issueRules }
67+
for (const rule in enforcedRules) {
68+
if (
69+
!defaultedRules[rule] ||
70+
ruleStrength(enforcedRules[rule]) > ruleStrength(defaultedRules[rule])
71+
) {
72+
defaultedRules[rule] = enforcedRules[rule]
73+
}
74+
}
6675
for (const rule in settings.defaultIssueRules) {
6776
if (!(rule in defaultedRules) || (
6877
typeof defaultedRules[rule] === 'object' &&
@@ -427,7 +436,7 @@ async function packagesHaveRiskyIssues (registry, pkgs, ora = null, input, outpu
427436

428437
for await (const pkgData of batchScan(pkgs.map(pkg => pkg.pkgid))) {
429438
let failures = []
430-
let warns = [];
439+
let warns = []
431440
if (pkgData.type === 'missing') {
432441
failures.push({
433442
type: 'missingDependency'
@@ -439,7 +448,7 @@ async function packagesHaveRiskyIssues (registry, pkgs, ora = null, input, outpu
439448
if (typeof rules[issue.type] == 'boolean' || rules[issue.type].action === 'error') {
440449
failures.push(issue)
441450
} else if (rules[issue.type].action == 'warn') {
442-
warns.push(issue);
451+
warns.push(issue)
443452
}
444453
}
445454
}

lib/utils/settings.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const settingsPath = path.join(dataHome, 'socket', 'settings')
2323
* @typedef {import('@socketsecurity/sdk').SocketSdkReturnType<'getSettings'>['data']['organizations'][string]['issueRules']} IssueRules
2424
*/
2525

26-
/** @type {{apiKey?: string | null, orgs?: { id: string, issueRules: IssueRules }[] | null}} */
26+
/** @type {{apiKey?: string | null, enforcedOrg?: string | null}} */
2727
let settings = {}
2828

2929
if (fs.existsSync(settingsPath)) {

0 commit comments

Comments
 (0)