Skip to content

Commit 8f7a0d9

Browse files
committed
feat: merge all machini methods to qsu package. machini package will be deprecated.
1 parent b462978 commit 8f7a0d9

File tree

12 files changed

+311
-1
lines changed

12 files changed

+311
-1
lines changed
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# getMachineId <Badge type="tip" text="JavaScript" />
2+
3+
<span class="node-required">Requires a Node.js runtime ('qsu/node')</span>
4+
5+
Gets the unique UUID of the current device. Throws an error if the value is not retrieved. Returns a `Promise` object, so use `await` or `.then()` to wait for the operation to complete and get the correct value.
6+
7+
The UUID may change when the system is reinstalled or as the virtual machine's environment changes. On some systems, this value can also be modified by the system administrator (but this is rarely utilized as the system may become unstable after modification).
8+
9+
This method returns the same value for every user on the system.
10+
11+
## Parameters
12+
13+
No required parameters
14+
15+
## Returns
16+
17+
> string
18+
19+
## Examples
20+
21+
```javascript
22+
console.log(await getMachineId()); // Returns 'a642d9e1-6063-4da7-8ea8-2298f989d01d'
23+
```

docs/src/en/reference/os/getSid.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# getSid <Badge type="tip" text="JavaScript" />
2+
3+
<span class="node-required">Requires a Node.js runtime ('qsu/node')</span>
4+
5+
Gets the Security Identifier (SID) value for the current user on the device. Throws an error if the value is not obtained.
6+
7+
The SID value is only supported on Windows and macOS. Other OSes throw an error.
8+
9+
Also, the SID value used on macOS is a value created for the directory service. If you don't trust this value, use the `machineId` method instead.
10+
11+
This value can be changed by the user.
12+
13+
## Parameters
14+
15+
No required parameters
16+
17+
## Returns
18+
19+
> string
20+
21+
## Examples
22+
23+
```javascript
24+
console.log(await sid()); // Returns 'S-1-5-21-406418252-5582013529-1321253100-2001'
25+
```
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# runCommand <Badge type="tip" text="JavaScript" />
2+
3+
<span class="node-required">Requires a Node.js runtime ('qsu/node')</span>
4+
5+
It returns the result that is output after entering and executing the command prompt command.
6+
7+
## Parameters
8+
9+
- `command::string`
10+
11+
## Returns
12+
13+
> string
14+
15+
## Examples
16+
17+
```javascript
18+
console.log(await runCommand('echo a')); // Returns 'a\n'
19+
```
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# getMachineId <Badge type="tip" text="JavaScript" />
2+
3+
<span class="node-required">Node.js 런타임 필요 ('qsu/node')</span>
4+
5+
현재 장치의 고유 UUID를 가져옵니다. 값을 가져오지 못하면 에러를 발생시킵니다. `Promise` 객체를 반환하므로, `await` 또는 `.then()`을 사용하여 작업이 완료될 때까지 기다렸다가 올바른 값을 얻으십시오.
6+
7+
UUID는 시스템을 재설치하거나 가상 머신의 환경이 변경될 때 변경될 수 있습니다. 일부 시스템에서는 시스템 관리자가 이 값을 수정할 수도 있습니다(그러나 시스템이 불안정해질 수 있으므로 거의 사용되지 않습니다).
8+
9+
이 방법은 시스템의 모든 사용자에게 동일한 값을 반환합니다.
10+
11+
## Parameters
12+
13+
필수 매개 변수 없음
14+
15+
## Returns
16+
17+
> string
18+
19+
## Examples
20+
21+
```javascript
22+
console.log(await getMachineId()); // Returns 'a642d9e1-6063-4da7-8ea8-2298f989d01d'
23+
```

docs/src/ko/reference/os/getSid.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# getSid <Badge type="tip" text="JavaScript" />
2+
3+
<span class="node-required">Node.js 런타임 필요 ('qsu/node')</span>
4+
5+
장치의 현재 사용자에 대한 보안 식별자(SID) 값을 가져옵니다. 값을 가져오지 못하면 에러를 발생시킵니다.
6+
7+
SID 값은 윈도우와 맥OS에서만 지원됩니다. 다른 운영 체제에서는 오류가 발생합니다.
8+
9+
또한, 맥OS에서 사용되는 SID 값은 디렉토리 서비스를 위해 생성된 값입니다. 이 값을 신뢰하지 않는다면, 대신 `machineId` 방법을 사용하십시오.
10+
11+
이 값은 사용자가 변경할 수 있습니다.
12+
13+
## Parameters
14+
15+
필수 매개 변수 없음
16+
17+
## Returns
18+
19+
> string
20+
21+
## Examples
22+
23+
```javascript
24+
console.log(await sid()); // Returns 'S-1-5-21-406418252-5582013529-1321253100-2001'
25+
```
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# runCommand <Badge type="tip" text="JavaScript" />
2+
3+
<span class="node-required">Node.js 런타임 필요 ('qsu/node')</span>
4+
5+
명령 프롬프트 커맨드를 입력하고 실행 후 출력되는 결과를 리턴합니다.
6+
7+
## Parameters
8+
9+
- `command::string`
10+
11+
## Returns
12+
13+
> string
14+
15+
## Examples
16+
17+
```javascript
18+
console.log(await runCommand('echo a')); // Returns 'a\n'
19+
```

packages/javascript/lib/node/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
export * from './file/index.js';
21
export * from './crypto/index.js';
2+
export * from './file/index.js';
3+
export * from './os/index.js';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { platform } from 'os';
2+
import { runCommand } from './runCommand.js';
3+
4+
export async function getMachineId(): Promise<string> {
5+
const platformName = platform();
6+
let command;
7+
8+
if (platformName === 'win32') {
9+
command =
10+
'for /f "tokens=3 delims= " %i in (\'REG QUERY HKLM\\SOFTWARE\\Microsoft\\Cryptography /v MachineGuid ^| findstr MachineGuid\') do @echo %i';
11+
} else if (platformName === 'darwin') {
12+
command = "ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/' | cut -d '\"' -f4";
13+
} else if (platformName === 'freebsd') {
14+
command = 'kenv -q smbios.system.uuid || sysctl -n kern.hostuuid';
15+
} else {
16+
command =
17+
'(cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname) | head -n 1 || :';
18+
}
19+
20+
try {
21+
return await runCommand(command);
22+
} catch (error) {
23+
if (error instanceof Error) {
24+
throw new Error(error?.message);
25+
}
26+
}
27+
28+
throw new Error('Failed to get machine id');
29+
}
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { homedir, platform, userInfo } from 'os';
2+
import { AnyValueObject } from '../../_types/global';
3+
import { runCommand } from './runCommand.js';
4+
5+
export async function getSid(): Promise<string> {
6+
const platformName = platform();
7+
8+
if (platformName === 'win32') {
9+
try {
10+
const profileLists = await runCommand(
11+
`REG QUERY "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList" /s`
12+
);
13+
14+
const profiles: AnyValueObject = {};
15+
const sections = profileLists.split('HKEY_LOCAL_MACHINE\\');
16+
17+
sections.forEach((section) => {
18+
const lines = section
19+
.split('\n')
20+
.map((line) => line.trim())
21+
.filter((line) => line);
22+
23+
if (lines.length > 0) {
24+
const keyName: string = lines[0].split('\\').pop() || 'Unknown';
25+
const profileImagePath = lines.find((line) => line.startsWith('ProfileImagePath'));
26+
27+
if (profileImagePath) {
28+
profiles[keyName] = profileImagePath.split(' ').pop() || 'Unknown';
29+
}
30+
}
31+
});
32+
33+
for (let i = 0; i < Object.keys(profiles).length; i += 1) {
34+
const key = Object.keys(profiles)[i];
35+
const value = profiles[key];
36+
37+
if (value === homedir()) {
38+
return key;
39+
}
40+
}
41+
} catch (error) {
42+
if (error instanceof Error) {
43+
throw new Error(error?.message);
44+
}
45+
}
46+
47+
throw new Error('Failed to get machine id');
48+
}
49+
50+
if (platformName === 'darwin') {
51+
try {
52+
const execResult = await runCommand(`dsmemberutil getsid -U ${userInfo().username}`);
53+
54+
if (execResult) {
55+
return execResult.replace(/\r?\n/g, '');
56+
}
57+
} catch (error) {
58+
if (error instanceof Error) {
59+
throw new Error(error?.message);
60+
}
61+
}
62+
63+
throw new Error('Failed to get machine id');
64+
}
65+
66+
throw new Error('Not supported on this operating system.');
67+
}
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { getMachineId } from './getMachineId.js';
2+
export { getSid } from './getSid.js';
3+
export { runCommand } from './runCommand.js';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { exec as processExec } from 'child_process';
2+
import { platform } from 'os';
3+
4+
export function runCommand(command: string): Promise<string> {
5+
return new Promise((resolve, reject) => {
6+
const execCommandProcess = processExec(
7+
command,
8+
{ encoding: 'utf8', windowsHide: true },
9+
(error, stdout) => {
10+
if (error) {
11+
reject(error);
12+
return;
13+
}
14+
15+
const output = platform() === 'win32' ? stdout : stdout.split('\r\n')?.[0] || '';
16+
17+
execCommandProcess?.stdin?.end();
18+
19+
if (output) {
20+
resolve(output);
21+
return;
22+
}
23+
24+
reject(new Error(`Command failed`));
25+
}
26+
);
27+
});
28+
}

packages/javascript/test/os.test.ts

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import assert from 'assert';
2+
import { describe, it } from 'node:test';
3+
import { runCommand, getMachineId, getSid } from '../dist/node';
4+
5+
describe('OS', () => {
6+
it('runCommand', async () => {
7+
assert.strictEqual(await runCommand('echo a'), 'a\n');
8+
assert.strictEqual(await runCommand('echo b'), 'b\n');
9+
});
10+
11+
/*
12+
* Sample Response:
13+
* Windows: a642d9e1-6063-4da7-8ea8-2298f989d01d
14+
* Linux: 5c6ee51d3e514eb4883e4373e320192c
15+
* macOS: BAC04154-124A-56E1-BFEB-D6D94FE5DBC0
16+
*/
17+
it('getMachineId', async () => {
18+
const mId = await getMachineId();
19+
20+
let regex;
21+
22+
switch (process.platform) {
23+
case 'win32':
24+
case 'darwin':
25+
case 'freebsd':
26+
regex = /^[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}/;
27+
break;
28+
default:
29+
regex = /^[0-9a-zA-Z]{8}-?[0-9a-zA-Z]{4}-?[0-9a-zA-Z]{4}-?[0-9a-zA-Z]{4}-?[0-9a-zA-Z]{12}/;
30+
break;
31+
}
32+
33+
assert.match(mId, regex);
34+
});
35+
36+
// Example: S-1-5-21-406418252-5582013529-1321253100-2001
37+
it('getSid', async () => {
38+
const { platform } = process;
39+
40+
if (platform !== 'win32' && platform !== 'darwin') {
41+
return;
42+
}
43+
44+
const sidResult = await getSid();
45+
46+
assert.match(sidResult, /^S-1-[0-59]-\d{2}-\d{8,10}-\d{8,10}-\d{8,10}-[1-9]\d{1,9}/);
47+
});
48+
});

0 commit comments

Comments
 (0)