1#!/usr/bin/env node
2/* Based on ui/app.js from Sshwifty. */
3const { subtle } = require('node:crypto')
4const sshwiftyURL = 'http://localhost/sshwifty/socket/verify'
5const sharedKey = 'rpz2E4QI6uPMLr'
6const serverMessage = 'NixOS test'
7
8async function hmac512(secret, data) {
9 const key = await subtle.importKey(
10 'raw',
11 secret,
12 { name: 'HMAC', hash: { name: 'SHA-512' } },
13 false,
14 ['sign', 'verify'],
15 )
16 return subtle.sign(key.algorithm, key, data)
17}
18
19async function getSocketAuthKey(privateKey) {
20 const enc = new TextEncoder(),
21 rTime = Number(Math.trunc(Date.now() / 100000))
22 return new Uint8Array(
23 await hmac512(enc.encode(privateKey), enc.encode(rTime)),
24 ).slice(0, 32)
25}
26
27async function requestAuth(privateKey) {
28 const authKey = await getSocketAuthKey(privateKey)
29 const h = await fetch(sshwiftyURL, {
30 headers: { 'X-Key': btoa(String.fromCharCode.apply(null, authKey)) },
31 })
32 const serverDate = h.headers.get('Date')
33 return {
34 result: h.status,
35 date: serverDate ? new Date(serverDate) : null,
36 text: await h.text(),
37 }
38}
39
40async function tryInitialAuth() {
41 try {
42 const result = await requestAuth(sharedKey)
43 if (result.date) {
44 const serverRespondTime = result.date,
45 serverRespondTimestamp = serverRespondTime.getTime(),
46 clientCurrent = new Date(),
47 clientTimestamp = clientCurrent.getTime(),
48 timeDiff = Math.abs(serverRespondTimestamp - clientTimestamp)
49 if (timeDiff > 30000) {
50 console.log('Time difference between client and server too big.')
51 process.exit(1)
52 }
53 }
54 switch (result.result) {
55 case 200:
56 if (result.text.includes(serverMessage)) {
57 console.log('All good.')
58 process.exit()
59 } else {
60 console.log('Server message not found')
61 process.exit(1)
62 }
63 break
64 case 403:
65 console.log('We need auth.')
66 process.exit(1)
67 break
68 case 0:
69 console.log('Timeout?')
70 process.exit(1)
71 break
72 default:
73 console.log('wghat')
74 process.exit(1)
75 }
76 } catch {
77 console.log('Something went horribly wrong, ouch.')
78 process.exit(1)
79 }
80}
81
82console.log('Testing Sshwifty')
83tryInitialAuth()