@openclaw/nostr 2026.2.21 → 2026.2.23

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 2026.2.22
4
+
5
+ ### Changes
6
+
7
+ - Version alignment with core OpenClaw release numbers.
8
+
3
9
  ## 2026.1.19-1
4
10
 
5
11
  Initial release.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/nostr",
3
- "version": "2026.2.21",
3
+ "version": "2026.2.23",
4
4
  "description": "OpenClaw Nostr channel plugin for NIP-04 encrypted DMs",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -204,6 +204,23 @@ describe("nostr-profile-http", () => {
204
204
  });
205
205
 
206
206
  describe("PUT /api/channels/nostr/:accountId/profile", () => {
207
+ async function expectPrivatePictureRejected(pictureUrl: string) {
208
+ const ctx = createMockContext();
209
+ const handler = createNostrProfileHttpHandler(ctx);
210
+ const req = createMockRequest("PUT", "/api/channels/nostr/default/profile", {
211
+ name: "hacker",
212
+ picture: pictureUrl,
213
+ });
214
+ const res = createMockResponse();
215
+
216
+ await handler(req, res);
217
+
218
+ expect(res._getStatusCode()).toBe(400);
219
+ const data = JSON.parse(res._getData());
220
+ expect(data.ok).toBe(false);
221
+ expect(data.error).toContain("private");
222
+ }
223
+
207
224
  it("validates profile and publishes", async () => {
208
225
  const ctx = createMockContext();
209
226
  const handler = createNostrProfileHttpHandler(ctx);
@@ -263,37 +280,11 @@ describe("nostr-profile-http", () => {
263
280
  });
264
281
 
265
282
  it("rejects private IP in picture URL (SSRF protection)", async () => {
266
- const ctx = createMockContext();
267
- const handler = createNostrProfileHttpHandler(ctx);
268
- const req = createMockRequest("PUT", "/api/channels/nostr/default/profile", {
269
- name: "hacker",
270
- picture: "https://127.0.0.1/evil.jpg",
271
- });
272
- const res = createMockResponse();
273
-
274
- await handler(req, res);
275
-
276
- expect(res._getStatusCode()).toBe(400);
277
- const data = JSON.parse(res._getData());
278
- expect(data.ok).toBe(false);
279
- expect(data.error).toContain("private");
283
+ await expectPrivatePictureRejected("https://127.0.0.1/evil.jpg");
280
284
  });
281
285
 
282
286
  it("rejects ISATAP-embedded private IPv4 in picture URL", async () => {
283
- const ctx = createMockContext();
284
- const handler = createNostrProfileHttpHandler(ctx);
285
- const req = createMockRequest("PUT", "/api/channels/nostr/default/profile", {
286
- name: "hacker",
287
- picture: "https://[2001:db8:1234::5efe:127.0.0.1]/evil.jpg",
288
- });
289
- const res = createMockResponse();
290
-
291
- await handler(req, res);
292
-
293
- expect(res._getStatusCode()).toBe(400);
294
- const data = JSON.parse(res._getData());
295
- expect(data.ok).toBe(false);
296
- expect(data.error).toContain("private");
287
+ await expectPrivatePictureRejected("https://[2001:db8:1234::5efe:127.0.0.1]/evil.jpg");
297
288
  });
298
289
 
299
290
  it("rejects non-https URLs", async () => {