@shoru/kitten 0.0.6 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,97 @@
1
+ import qrcode from 'qrcode-terminal';
2
+ import chalk from 'chalk';
3
+ import { ConnectionError } from './errors.js';
4
+ import { ClientRegistry } from './registry.js';
5
+ import { getConnectionConfig } from './getConnectionConfig.js';
6
+
7
+ /**
8
+ * Formats a pairing code into readable 4-character groups with styling.
9
+ *
10
+ * @param {string} code - The raw pairing code string
11
+ * @returns {string} The styled formatted pairing code
12
+ */
13
+ export function formatPairingCode(code) {
14
+ const formatted = code.match(/.{1,4}/g)?.join(' ') ?? code;
15
+ return `\n${chalk.green('> Your OTP Code: ')}${chalk.bold(formatted)}`;
16
+ }
17
+
18
+ /**
19
+ * Handles authentication for a client instance when a QR code or pairing challenge is received.
20
+ *
21
+ * @param {object} params
22
+ * @param {string} params.qr - The QR code string
23
+ * @param {any} params.rawSock - The raw WASocket instance
24
+ * @param {string} params.flag - Identifier string for logging
25
+ * @param {boolean} params.isSync - Whether the client is a background sync instance
26
+ * @param {boolean} params.isSilent - Whether logging/prompts are suppressed
27
+ * @param {Function|null} params.onPairing - Optional custom pairing callback
28
+ * @param {object} params.logger - Logger instance
29
+ * @param {object|null} params.authConfig - Cached auth config
30
+ * @param {(config: object|null) => void} params.setAuthConfig - Setter for auth config
31
+ * @param {boolean} params.pairingCodeRequested - Whether pairing code has already been requested
32
+ * @param {(requested: boolean) => void} params.setPairingCodeRequested - Setter for pairingCodeRequested
33
+ * @param {(err: Error) => void} params.onSyncAuthAbort - Callback when sync connection requires auth
34
+ */
35
+ export async function handleClientAuth({
36
+ qr,
37
+ rawSock,
38
+ flag,
39
+ isSync,
40
+ isSilent,
41
+ onPairing,
42
+ logger,
43
+ authConfig,
44
+ setAuthConfig,
45
+ pairingCodeRequested,
46
+ setPairingCodeRequested,
47
+ onSyncAuthAbort,
48
+ }) {
49
+ if (isSync) {
50
+ const err = new ConnectionError('Authentication required for sync connection', {
51
+ recoverable: false,
52
+ });
53
+ logger.debug(`[${flag}] Sync connection requires auth, aborting`);
54
+ onSyncAuthAbort(err);
55
+ return;
56
+ }
57
+
58
+ if (ClientRegistry.isConfiguring) return;
59
+
60
+ if (typeof onPairing === 'function') {
61
+ const requestPairingCode = rawSock?.requestPairingCode?.bind(rawSock);
62
+ await onPairing({ qr, requestPairingCode });
63
+ return;
64
+ }
65
+
66
+ if (isSilent) {
67
+ return;
68
+ }
69
+
70
+ let currentAuthConfig = authConfig;
71
+ if (!currentAuthConfig) {
72
+ ClientRegistry.isConfiguring = true;
73
+ try {
74
+ currentAuthConfig = await getConnectionConfig();
75
+ setAuthConfig(currentAuthConfig);
76
+ } finally {
77
+ ClientRegistry.isConfiguring = false;
78
+ }
79
+ }
80
+
81
+ if (currentAuthConfig.type === 'pn') {
82
+ if (!pairingCodeRequested && rawSock) {
83
+ try {
84
+ setPairingCodeRequested(true);
85
+ const code = await rawSock.requestPairingCode(currentAuthConfig.pn);
86
+ logger.prompt(formatPairingCode(code));
87
+ } catch (err) {
88
+ setPairingCodeRequested(false);
89
+ logger.error(err, `[${flag}] Failed to request pairing code`);
90
+ }
91
+ }
92
+ } else {
93
+ qrcode.generate(qr, { small: true });
94
+ process.stdout.write('\n');
95
+ }
96
+ }
97
+