powerbin 0.1.0 → 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.
- package/README.md +8 -3
- package/dist/client.js +37 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,9 +46,14 @@ for invalid arguments or a malformed link.
|
|
|
46
46
|
|
|
47
47
|
## One-time behavior
|
|
48
48
|
|
|
49
|
-
Running `reveal`
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
Running `reveal` checks compatibility without consuming the link, then claims it
|
|
50
|
+
once. There is no confirmation prompt. Version 0.1.1 and later require the server
|
|
51
|
+
to report `protocol_version: 2` in its availability response. Older servers and
|
|
52
|
+
legacy v1 links are rejected before the consuming request. Update the PowerBin
|
|
53
|
+
server and browser app together, reload the browser, and create a fresh link.
|
|
54
|
+
|
|
55
|
+
Missing or malformed keys are rejected before contacting the server. A validly
|
|
56
|
+
encoded but incorrect key can still consume the message before decryption fails.
|
|
52
57
|
|
|
53
58
|
The CLI never retries or follows redirects for the consuming request. If the
|
|
54
59
|
response is lost after the server claims the message, it cannot be recovered.
|
package/dist/client.js
CHANGED
|
@@ -91,11 +91,47 @@ async function responseBody(response) {
|
|
|
91
91
|
}
|
|
92
92
|
return new TextDecoder('utf-8', { fatal: true }).decode(Buffer.concat(chunks));
|
|
93
93
|
}
|
|
94
|
-
|
|
94
|
+
async function checkProtocol(link, timeoutMs) {
|
|
95
|
+
let response;
|
|
96
|
+
try {
|
|
97
|
+
response = await fetch(link.endpoint.slice(0, -'/reveal'.length), {
|
|
98
|
+
method: 'GET',
|
|
99
|
+
headers: { Accept: 'application/json' },
|
|
100
|
+
redirect: 'manual',
|
|
101
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
throw new CliError('The link availability check was lost or timed out. This request did not consume the message.');
|
|
106
|
+
}
|
|
107
|
+
if (response.status >= 300 && response.status < 400) {
|
|
108
|
+
await response.body?.cancel().catch(() => { });
|
|
109
|
+
throw new CliError('The service redirected the availability check. No redirect was followed. This request did not consume the message.');
|
|
110
|
+
}
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
await response.body?.cancel().catch(() => { });
|
|
113
|
+
const reason = [400, 401, 403, 404, 410, 429].includes(response.status)
|
|
114
|
+
? statusError(response.status).message
|
|
115
|
+
: 'The server could not check this link.';
|
|
116
|
+
throw new CliError(`${reason} This request did not consume the message.`);
|
|
117
|
+
}
|
|
118
|
+
let metadata;
|
|
119
|
+
try {
|
|
120
|
+
metadata = JSON.parse(await responseBody(response));
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
throw new CliError('The link metadata response was incomplete or invalid. This request did not consume the message.');
|
|
124
|
+
}
|
|
125
|
+
if (!metadata || typeof metadata !== 'object' || !('protocol_version' in metadata) || metadata.protocol_version !== 2) {
|
|
126
|
+
throw new CliError('This link/server uses an unsupported encryption format. Update PowerBin server/browser, then create a new link. This request did not consume the message.');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/** Check compatibility without consuming, then make a single consuming request. */
|
|
95
130
|
export async function revealLink(input, options = {}) {
|
|
96
131
|
const link = parseLink(input);
|
|
97
132
|
try {
|
|
98
133
|
const crypto = loadCrypto();
|
|
134
|
+
await checkProtocol(link, options.timeoutMs ?? 15_000);
|
|
99
135
|
let response;
|
|
100
136
|
try {
|
|
101
137
|
response = await fetch(link.endpoint, {
|