|
| 1 | +import { test } from "node:test"; |
| 2 | +import assert from "node:assert/strict"; |
| 3 | + |
| 4 | +import { request as defaultRequest } from "@octokit/request"; |
| 5 | +import { MockAgent } from "undici"; |
| 6 | + |
| 7 | +import { verify } from "../index.js"; |
| 8 | + |
| 9 | +const RAW_BODY = `{"copilot_thread_id":"9a1cc23a-ab73-498b-87a5-96c94cb7e3f3","messages":[{"role":"user","content":"@gr2m hi","copilot_references":[{"type":"github.repository","data":{"type":"repository","id":102985470,"name":"sandbox","ownerLogin":"gr2m","ownerType":"User","readmePath":"README.md","description":"@gr2m's little sandbox to play","commitOID":"9b04fffccbb818b2e317394463731b66f1ec5e89","ref":"refs/heads/main","refInfo":{"name":"main","type":"branch"},"visibility":"public","languages":[{"name":"JavaScript","percent":100}]},"id":"gr2m/sandbox","is_implicit":false,"metadata":{"display_name":"gr2m/sandbox","display_icon":"","display_url":""}}],"copilot_confirmations":null},{"role":"user","content":"@gr2m test","copilot_references":[{"type":"github.repository","data":{"type":"repository","id":102985470,"name":"sandbox","ownerLogin":"gr2m","ownerType":"User","readmePath":"README.md","description":"@gr2m's little sandbox to play","commitOID":"9b04fffccbb818b2e317394463731b66f1ec5e89","ref":"refs/heads/main","refInfo":{"name":"main","type":"branch"},"visibility":"public","languages":[{"name":"JavaScript","percent":100}]},"id":"gr2m/sandbox","is_implicit":false,"metadata":{"display_name":"gr2m/sandbox","display_icon":"","display_url":""}}],"copilot_confirmations":null},{"role":"user","content":"@gr2m test","copilot_references":[{"type":"github.repository","data":{"type":"repository","id":102985470,"name":"sandbox","ownerLogin":"gr2m","ownerType":"User","readmePath":"README.md","description":"@gr2m's little sandbox to play","commitOID":"9b04fffccbb818b2e317394463731b66f1ec5e89","ref":"refs/heads/main","refInfo":{"name":"main","type":"branch"},"visibility":"public","languages":[{"name":"JavaScript","percent":100}]},"id":"gr2m/sandbox","is_implicit":false,"metadata":{"display_name":"gr2m/sandbox","display_icon":"","display_url":""}}],"copilot_confirmations":null},{"role":"user","content":"Current Date and Time (UTC): 2024-08-26 19:43:13\\nUser's Current URL: https://github.com/gr2m/sandbox\\nCurrent User's Login: gr2m\\n","name":"_session","copilot_references":[],"copilot_confirmations":null},{"role":"user","content":"","copilot_references":[{"type":"github.repository","data":{"type":"repository","id":102985470,"name":"sandbox","ownerLogin":"gr2m","ownerType":"User","readmePath":"README.md","description":"@gr2m's little sandbox to play","commitOID":"9b04fffccbb818b2e317394463731b66f1ec5e89","ref":"refs/heads/main","refInfo":{"name":"main","type":"branch"},"visibility":"public","languages":[{"name":"JavaScript","percent":100}]},"id":"gr2m/sandbox","is_implicit":false,"metadata":{"display_name":"gr2m/sandbox","display_icon":"","display_url":""}}],"copilot_confirmations":null},{"role":"user","content":"test","copilot_references":[],"copilot_confirmations":[]}],"stop":null,"top_p":0,"temperature":0,"max_tokens":0,"presence_penalty":0,"frequency_penalty":0,"copilot_skills":null,"agent":"gr2m"}`; |
| 10 | +const KEY_ID = |
| 11 | + "4fe6b016179b74078ade7581abf4e84fb398c6fae4fb973972235b84fcd70ca3"; |
| 12 | + |
| 13 | +const CURRENT_PUBLIC_KEY = `-----BEGIN PUBLIC KEY----- |
| 14 | +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELPuPiLVQbHY/clvpNnY+0BzYIXgo |
| 15 | +S0+XhEkTWUZEEznIVpS3rQseDTG6//gEWr4j9fY35+dGOxwOx3Z9mK3i7w== |
| 16 | +-----END PUBLIC KEY----- |
| 17 | +`; |
| 18 | + |
| 19 | +const SIGNATURE = |
| 20 | + "MEYCIQC8aEmkYA/4EQrXEOi2OL9nfpbnrCxkMc6HrH7b6SogKgIhAIYBThcpzkCCswiV1+pOaPI+zFQF9ShG61puoKs9rJjq"; |
| 21 | + |
| 22 | +test("smoke", (t) => { |
| 23 | + assert.equal(typeof verify, "function"); |
| 24 | +}); |
| 25 | + |
| 26 | +test("minimal usage", async (t) => { |
| 27 | + const mockAgent = new MockAgent(); |
| 28 | + function fetchMock(url, opts) { |
| 29 | + opts ||= {}; |
| 30 | + opts.dispatcher = mockAgent; |
| 31 | + return fetch(url, opts); |
| 32 | + } |
| 33 | + |
| 34 | + mockAgent.disableNetConnect(); |
| 35 | + const mockPool = mockAgent.get("https://api.github.com"); |
| 36 | + mockPool |
| 37 | + .intercept({ |
| 38 | + method: "get", |
| 39 | + path: `/meta/public_keys/copilot_api`, |
| 40 | + }) |
| 41 | + .reply( |
| 42 | + 200, |
| 43 | + { |
| 44 | + public_keys: [ |
| 45 | + { |
| 46 | + key: CURRENT_PUBLIC_KEY, |
| 47 | + key_identifier: KEY_ID, |
| 48 | + is_current: true, |
| 49 | + }, |
| 50 | + ], |
| 51 | + }, |
| 52 | + { |
| 53 | + headers: { |
| 54 | + "content-type": "application/json", |
| 55 | + "x-request-id": "<request-id>", |
| 56 | + }, |
| 57 | + }, |
| 58 | + ); |
| 59 | + const testRequest = defaultRequest.defaults({ |
| 60 | + request: { fetch: fetchMock }, |
| 61 | + }); |
| 62 | + |
| 63 | + const result = await verify(RAW_BODY, SIGNATURE, KEY_ID, { |
| 64 | + request: testRequest, |
| 65 | + }); |
| 66 | + |
| 67 | + assert.deepEqual(result, true); |
| 68 | +}); |
| 69 | + |
| 70 | +test("invalid arguments", (t) => { |
| 71 | + assert.rejects(verify(RAW_BODY, SIGNATURE), { |
| 72 | + name: "Error", |
| 73 | + message: "[@copilot-extensions/preview-sdk] Invalid keyId", |
| 74 | + }); |
| 75 | + |
| 76 | + assert.rejects(verify("", SIGNATURE, KEY_ID), { |
| 77 | + name: "Error", |
| 78 | + message: "[@copilot-extensions/preview-sdk] Invalid payload", |
| 79 | + }); |
| 80 | + |
| 81 | + assert.rejects(verify(1, SIGNATURE, KEY_ID), { |
| 82 | + name: "Error", |
| 83 | + message: "[@copilot-extensions/preview-sdk] Invalid payload", |
| 84 | + }); |
| 85 | + |
| 86 | + assert.rejects(verify(undefined, SIGNATURE, KEY_ID), { |
| 87 | + name: "Error", |
| 88 | + message: "[@copilot-extensions/preview-sdk] Invalid payload", |
| 89 | + }); |
| 90 | + |
| 91 | + assert.rejects(verify(RAW_BODY, "", KEY_ID), { |
| 92 | + name: "Error", |
| 93 | + message: "[@copilot-extensions/preview-sdk] Invalid signature", |
| 94 | + }); |
| 95 | + |
| 96 | + assert.rejects(verify(RAW_BODY, 1, KEY_ID), { |
| 97 | + name: "Error", |
| 98 | + message: "[@copilot-extensions/preview-sdk] Invalid signature", |
| 99 | + }); |
| 100 | + |
| 101 | + assert.rejects(verify(RAW_BODY, undefined, KEY_ID), { |
| 102 | + name: "Error", |
| 103 | + message: "[@copilot-extensions/preview-sdk] Invalid signature", |
| 104 | + }); |
| 105 | + |
| 106 | + assert.rejects(verify(RAW_BODY, SIGNATURE, ""), { |
| 107 | + name: "Error", |
| 108 | + message: "[@copilot-extensions/preview-sdk] Invalid keyId", |
| 109 | + }); |
| 110 | + |
| 111 | + assert.rejects(verify(RAW_BODY, SIGNATURE, 1), { |
| 112 | + name: "Error", |
| 113 | + message: "[@copilot-extensions/preview-sdk] Invalid keyId", |
| 114 | + }); |
| 115 | + |
| 116 | + assert.rejects(verify(RAW_BODY, SIGNATURE, undefined), { |
| 117 | + name: "Error", |
| 118 | + message: "[@copilot-extensions/preview-sdk] Invalid keyId", |
| 119 | + }); |
| 120 | +}); |
0 commit comments