Skip to content

Commit a2203f7

Browse files
committed
feat(cli): validate device import data
1 parent b059ee1 commit a2203f7

File tree

3 files changed

+59
-16
lines changed

3 files changed

+59
-16
lines changed

cli/commands/import-devices.ts

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { type DynamoDBClient } from '@aws-sdk/client-dynamodb'
22
import type { SSMClient } from '@aws-sdk/client-ssm'
3+
import { isFingerprint } from '@hello.nrfcloud.com/proto/fingerprint'
34
import chalk from 'chalk'
5+
import { execSync } from 'node:child_process'
46
import { readFile } from 'node:fs/promises'
57
import os from 'node:os'
68
import { table } from 'table'
@@ -22,19 +24,59 @@ export const importDevicesCommand = ({
2224
}): CommandDefinition => ({
2325
command: 'import-devices <model> <provisioningList>',
2426
action: async (model, provisioningList) => {
25-
const devices: [imei: string, fingerprint: string, publicKey: string][] = (
26-
await readFile(provisioningList, 'utf-8')
27-
)
27+
const devicesList = (await readFile(provisioningList, 'utf-8'))
2828
.trim()
2929
.split('\r\n')
3030
.map((s) =>
3131
s.split(';').map((s) => s.replace(/^"/, '').replace(/"$/, '')),
3232
)
3333
.slice(1)
34-
.map(
35-
([imei, _, fingerprint, publicKey]) =>
36-
[imei, fingerprint, publicKey] as [string, string, string],
37-
)
34+
const devices: [imei: string, fingerprint: string, publicKey: string][] =
35+
devicesList
36+
.map(
37+
([imei, _, fingerprint, publicKey]) =>
38+
[imei, fingerprint, (publicKey ?? '').replace(/\\n/g, os.EOL)] as [
39+
string,
40+
string,
41+
string,
42+
],
43+
)
44+
.filter(([imei, fingerprint, publicKey]) => {
45+
if (!isIMEI(imei)) {
46+
console.error(
47+
chalk.yellow('⚠️'),
48+
chalk.yellow(`Not an IMEI:`),
49+
chalk.red(imei),
50+
)
51+
return false
52+
}
53+
if (!isFingerprint(fingerprint)) {
54+
console.error(
55+
chalk.yellow('⚠️'),
56+
chalk.yellow(`Not a fingerprint:`),
57+
chalk.red(fingerprint),
58+
)
59+
return false
60+
}
61+
try {
62+
execSync('openssl x509 -text -noout', { input: publicKey })
63+
} catch (err) {
64+
console.error(err)
65+
console.error(
66+
chalk.yellow('⚠️'),
67+
chalk.yellow(`Not a public key:`),
68+
chalk.red(publicKey),
69+
)
70+
return false
71+
}
72+
return true
73+
})
74+
75+
if (devices.length === 0) {
76+
console.error(chalk.red(`No devices found in`))
77+
console.error(devicesList)
78+
process.exit(1)
79+
}
3880

3981
console.log(
4082
table([
@@ -59,7 +101,7 @@ export const importDevicesCommand = ({
59101
const registration = await client.registerDevices(
60102
devices.map(([imei, _, publicKey]) => {
61103
const deviceId = `oob-${imei}`
62-
const certPem = publicKey.replace(/\\n/g, os.EOL)
104+
const certPem = publicKey
63105
return {
64106
deviceId,
65107
subType: model.replace(/[^0-9a-z-]/gi, '-'),
@@ -98,13 +140,14 @@ export const importDevicesCommand = ({
98140
console.error(res.error.message)
99141
} else {
100142
console.log(
101-
chalk.green(
102-
`Registered device ${deviceId} with fingerprint ${fingerprint}`,
103-
),
143+
chalk.green(`Registered device ${deviceId} with fingerprint`),
104144
chalk.cyan(fingerprint),
105145
)
106146
}
107147
}
108148
},
109149
help: 'Import factory provisioned devices',
110150
})
151+
152+
export const isIMEI = (imei?: string): imei is string =>
153+
/^35[0-9]{13}$/.test(imei ?? '')

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116
"prettier": "@nordicsemiconductor/asset-tracker-cloud-code-style/.prettierrc",
117117
"dependencies": {
118118
"@aws-lambda-powertools/metrics": "1.9.0",
119-
"@hello.nrfcloud.com/proto": "2.0.1",
119+
"@hello.nrfcloud.com/proto": "2.1.2",
120120
"@middy/core": "4.5.2",
121121
"@nordicsemiconductor/from-env": "2.0.0",
122122
"@nordicsemiconductor/timestream-helpers": "5.0.0",

0 commit comments

Comments
 (0)