2
0
Fork
You've already forked cup2
0
TypeScript implementation of the Chromium/Omaha Client Update Protocol
  • TypeScript 100%
2025年04月13日 10:02:21 +00:00
.github/workflows ci/jsr: set permissions for test workflow 2025年04月13日 10:02:21 +00:00
lib initial commit 2025年04月13日 09:10:02 +00:00
client.ts src: more docs 2025年04月13日 09:59:38 +00:00
client_test.ts initial commit 2025年04月13日 09:10:02 +00:00
deno.json src: more docs 2025年04月13日 09:59:38 +00:00
deno.lock initial commit 2025年04月13日 09:10:02 +00:00
LICENSE initial commit 2025年04月13日 09:10:02 +00:00
mod.ts initial commit 2025年04月13日 09:10:02 +00:00
mod_test.ts initial commit 2025年04月13日 09:10:02 +00:00
participant.ts initial commit 2025年04月13日 09:10:02 +00:00
README.md add install instructions 2025年04月13日 09:24:49 +00:00
server.ts src: more docs 2025年04月13日 09:59:38 +00:00

@imput/cup2

Client/server implementation of the Chromium/Omaha CUP-ECDSA protocol in Typescript.

Installation

  • Deno: deno add @imput/cup2
  • Node.js: npx jsr add @imput/cup2

Examples

client

import { CupClient } from '@imput/cup2';
const keyId = /* your key ID goes here */;
const keyBytes = new Uint8Array([
 /* your EC pubkey bytes go here, or you can load it from a file */
]);
// This is the side of the requestor of resources,
// which is usually a browser reaching out to some API.
const publicKey = await crypto.subtle.importKey(
 'spki', keyBytes,
 { name: 'ECDSA', namedCurve: 'P-256' },
 false, ['verify'],
);
const client = new CupClient(keyId, publicKey);
const raw_request = new Request('http://clients2.google.com/time/1/current');
const { request, ticket } = await client.wrap(raw_request);
// make the request after adding cup parameters
const response = await fetch(request);
// verify() throws a CupError if the signature is not valid
await client.verify(response, ticket);
// we can now consume the response
console.log(await response.text());

server

import { CupServer } from '@imput/cup2';
const keys: Record<number, CryptoKey> = {
 /* keys should be periodically rotated,
 but we still need to support older
 clients. this is why you are able to
 insert multiple keys here. load them
 from a file or something, this is entirely
 up to you
 */
};
const cup = new CupServer(keys);
Deno.serve(async (request: Request) => {
 // this library assumes all your incoming requests use CUP.
 // if this is not the case, you need to check for presence
 // of cup2key in request.url.searchParams and decide whether
 // you want to use CUP or not

 // this is separated from the signing process
 // so that we can do some preliminary checks and not
 // waste processing time if the request does not meet the
 // preconditions.
 const ticket = await cup.makeTicket(request);
 // hold on to this ticket, do some work ...
 // ...
 // we have a response!
 const response = new Response();
 // sign and return
 // TODO: cup.* methods throw a CupError if something
 // is wrong -- you probably want to check for that.
 return cup.sign(response, ticket);
});

more:

License

AGPL-3.0, see LICENSE.

For other licensing options, you can reach us at meow [@] imput.net.