Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose issuer as a worker service binding #78

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

# Step 1: Remove dist directory
rm -rf dist

# Step 2: Run npm build
npm run build

# Check if npm run build was successful
if [ $? -eq 0 ]; then
# If npm build succeeded, run the following git commands:
gaa && gcan! && git push --force myfork $(git branch --show-current) && gcopy
else
echo "Build failed, aborting git commands."
exit 1
fi

49 changes: 47 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,51 @@
dist
# Ignore
node_modules
transpiled
coverage
worker.mjs*
# worker.mjs*
.wrangler
# *.js.map

# # Ignore everything inside dist/
# dist/*

# # Un-ignore the dist directory itself so Git can look inside it
# !dist/

# # Allow specific files inside dist/
# !dist/router.js
# !dist/index.js

# # Ignore everything inside dist/context
# dist/context/*

# # Un-ignore the dist/context folder
# !dist/context/

# # Allow only specific files inside dist/context/
# !dist/context/index.js
# !dist/context/logging.js
# !dist/context/metrics.js

# # Ignore everything inside dist/types
# dist/types/*

# # Un-ignore the dist/types folder
# !dist/types/

# # Allow specific files inside dist/types/
# !dist/types/index.d.ts
# !dist/types/router.d.ts
# !dist/types/bindings.d.ts

# # Ignore everything inside dist/types/context
# dist/types/context/*

# # Un-ignore the dist/types/context folder
# !dist/types/context/

# # Allow only specific files inside dist/types/context/
# !dist/types/context/index.d.ts
# !dist/types/context/logging.d.ts
# !dist/types/context/metrics.d.ts

23 changes: 23 additions & 0 deletions dist/bindings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/// <reference types="@cloudflare/workers-types" />
import type { R2Bucket, Performance } from '@cloudflare/workers-types/2023-07-01';
import { IssuerHandler } from '.';
export interface Bindings {
DIRECTORY_CACHE_MAX_AGE_SECONDS: string;
ENVIRONMENT: string;
SERVICE: string;
SENTRY_ACCESS_CLIENT_ID: string;
SENTRY_ACCESS_CLIENT_SECRET: string;
SENTRY_DSN: string;
SENTRY_SAMPLE_RATE: string;
ISSUANCE_KEYS: R2Bucket;
PERFORMANCE: Performance | undefined;
VERSION_METADATA: ScriptVersion;
ROTATION_CRON_STRING?: string;
KEY_LIFESPAN_IN_MS: string;
KEY_NOT_BEFORE_DELAY_IN_MS: string;
MINIMUM_FRESHEST_KEYS: string;
LOGGING_SHIM_TOKEN: string;
WSHIM_SOCKET?: Fetcher;
WSHIM_ENDPOINT: string;
PRIVACYPASS_ISSUER: Service<IssuerHandler>;
}
75 changes: 75 additions & 0 deletions dist/cache.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/// <reference types="@cloudflare/workers-types" />
import { R2HTTPMetadata, R2ListOptions } from '@cloudflare/workers-types/2023-07-01';
import { Context } from './context';
export declare const getDirectoryCache: () => Promise<Cache>;
export declare const DIRECTORY_CACHE_REQUEST: (hostname: string) => Request<unknown, CfProperties<unknown>>;
export declare const clearDirectoryCache: (ctx: Context) => Promise<boolean>;
export type CacheElement<T> = {
value: T;
expiration: Date;
};
interface ReadableCache {
read<T>(key: string, setValFn: (key: string) => Promise<CacheElement<T>>): Promise<T>;
}
export declare const STALE_WHILE_REVALIDATE_IN_MS = 30000;
export declare function shouldRevalidate(expirationDate: Date): boolean;
export declare class InMemoryCryptoKeyCache {
private ctx;
private static store;
constructor(ctx: Context);
read(key: string, setValFn: (key: string) => Promise<CacheElement<CryptoKey>>): Promise<CryptoKey>;
}
export declare class InMemoryCache implements ReadableCache {
private ctx;
private static store;
constructor(ctx: Context);
read<T>(key: string, setValFn: (key: string) => Promise<CacheElement<T>>): Promise<T>;
}
export declare class APICache implements ReadableCache {
private ctx;
private cacheKey;
constructor(ctx: Context, cacheKey: string);
read<T>(key: string, setValFn: (key: string) => Promise<CacheElement<T>>): Promise<T>;
}
export declare class CascadingCache implements ReadableCache {
private caches;
constructor(...caches: ReadableCache[]);
read<T>(key: string, setValFn: (key: string) => Promise<CacheElement<T>>): Promise<T>;
}
export declare const DEFAULT_R2_BUCKET_CACHE_TTL_IN_MS: number;
export declare class CachedR2Object {
data?: Uint8Array | undefined;
checksums: R2Checksums;
customMetadata?: Record<string, string>;
etag: string;
httpEtag: string;
httpMetadata?: R2HTTPMetadata;
key: string;
size: number;
uploaded: Date;
version: string;
constructor(object: R2Object, data?: Uint8Array | undefined);
}
export declare class CachedR2Objects {
delimitedPrefixes: string[];
objects: CachedR2Object[];
truncated: boolean;
constructor(objects: R2Objects);
}
export interface CachedR2BucketOptions {
shouldUseCache?: boolean;
}
export declare class CachedR2Bucket {
private ctx;
private cache;
private ttl_in_ms;
private bucket;
constructor(ctx: Context, bucket: R2Bucket, cache: ReadableCache, ttl_in_ms?: number);
private shouldUseCache;
head(key: string, options?: CachedR2BucketOptions): Promise<CachedR2Object | null>;
list(options?: R2ListOptions & CachedR2BucketOptions): Promise<CachedR2Objects>;
get(key: string, options?: R2GetOptions & CachedR2BucketOptions): Promise<CachedR2Object | null>;
put(...args: Parameters<typeof R2Bucket.prototype.put>): ReturnType<typeof R2Bucket.prototype.put>;
delete(...args: Parameters<typeof R2Bucket.prototype.delete>): ReturnType<typeof R2Bucket.prototype.delete>;
}
export {};
34 changes: 34 additions & 0 deletions dist/context/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/// <reference types="@cloudflare/workers-types" />
import { Bindings } from '../bindings';
import { CachedR2Bucket } from '../cache';
import { Logger, WshimLogger } from './logging';
import { MetricsRegistry } from './metrics';
export type WaitUntilFunc = (p: Promise<unknown>) => void;
export declare class Context {
env: Bindings;
private _waitUntil;
logger: Logger;
metrics: MetricsRegistry;
wshimLogger: WshimLogger;
hostname: string;
startTime: number;
private promises;
bucket: {
ISSUANCE_KEYS: CachedR2Bucket;
};
performance: Performance;
constructor(request: Request, env: Bindings, _waitUntil: WaitUntilFunc, logger: Logger, metrics: MetricsRegistry, wshimLogger: WshimLogger);
isTest(): boolean;
/**
* Registers async tasks with the runtime, tracks them internally and adds error reporting for uncaught exceptions
* @param p - Promise for the async task to track
*/
waitUntil(p: Promise<unknown>): void;
/**
* Waits for promises to complete in the order that they were registered.
*
* @remark
* It is important to wait for the promises in the array to complete sequentially since new promises created by async tasks may be added to the end of the array while this function runs.
*/
waitForPromises(): Promise<void>;
}
86 changes: 86 additions & 0 deletions dist/context/logging.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/// <reference types="@cloudflare/workers-types" />
import type { Context } from 'toucan-js/dist/types';
import { Toucan } from 'toucan-js';
import { Breadcrumb } from '@sentry/types';
import { Bindings } from '../bindings';
export interface Logger {
captureException(err: Error): void;
addBreadcrumb(breadcrumb: Breadcrumb): void;
setTag(key: string, value: string): void;
setSampleRate(sampleRate: number): void;
info(category: string, message: string, data?: {
[key: string]: any;
}): void;
}
interface SentryOptions {
context: Context;
request: Request;
service: string;
dsn: string;
accessClientId: string;
accessClientSecret: string;
release: string;
sampleRate?: number;
coloName?: string;
}
export declare class FlexibleLogger implements Logger {
logger: Logger;
constructor(environment: string, options: SentryOptions);
addBreadcrumb(breadcrumb: Breadcrumb): void;
captureException(e: Error): void;
setTag(key: string, value: string): void;
setSampleRate(sampleRate: number): void;
info(category: string, message: string, data?: {
[key: string]: any;
}): void;
}
export declare class SentryLogger implements Logger {
sentry: Toucan;
context: Context;
request: Request;
environment: string;
service: string;
sampleRate: number;
constructor(environment: string, options: SentryOptions);
setTag(key: string, value: string): void;
setSampleRate(sampleRate: number): void;
addBreadcrumb(breadcrumb: Breadcrumb): void;
captureException(err: Error): void;
info(category: string, message: string, data?: {
[key: string]: any;
}): void;
}
export declare class ConsoleLogger implements Logger {
captureException(err: Error): void;
setTag(key: string, value: string): void;
setSampleRate(sampleRate: number): void;
addBreadcrumb(breadcrumb: Breadcrumb): void;
info(category: string, message: string, data?: {
[key: string]: any;
}): void;
}
export declare class VoidLogger implements Logger {
setTag(key: string, value: string): void;
setSampleRate(sampleRate: number): void;
addBreadcrumb(breadcrumb: Breadcrumb): void;
captureException(e: Error): void;
info(category: string, message: string, data?: {
[key: string]: any;
}): void;
}
export declare class WshimLogger {
private request;
private env;
private logs;
private serviceToken;
private sampleRate;
private fetcher;
private loggingEndpoint;
constructor(request: Request, env: Bindings, sampleRate?: number);
private shouldLog;
private defaultFields;
log(...msg: unknown[]): void;
error(...msg: unknown[]): void;
flushLogs(): Promise<void>;
}
export {};
48 changes: 48 additions & 0 deletions dist/context/metrics.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/// <reference types="@cloudflare/workers-types" />
import { CounterType, HistogramType, RegistryType } from 'promjs';
import { Bindings } from '../bindings';
export declare const KeyError: {
NOT_FOUND: string;
INVALID_PRIVATE_KEY: string;
MISSING_PRIVATE_KEY: string;
MISSING_PUBLIC_KEY: string;
};
interface RegistryOptions {
endpoint: string;
bearerToken: string;
fetcher: typeof fetch;
}
export interface DefaultLabels {
env: string;
service: string;
}
/**
* A wrapper around the promjs registry to manage registering and publishing metrics
*/
export declare class MetricsRegistry {
env: Bindings;
options: RegistryOptions;
registry: RegistryType;
asyncRetriesTotal: CounterType;
directoryCacheMissTotal: CounterType;
erroredRequestsTotal: CounterType;
issuanceKeyErrorTotal: CounterType;
issuanceRequestTotal: CounterType;
keyRotationTotal: CounterType;
keyClearTotal: CounterType;
requestsDurationMs: HistogramType;
requestsTotal: CounterType;
r2RequestsDurationMs: HistogramType;
signedTokenTotal: CounterType;
constructor(env: Bindings);
private defaultLabels;
private createCounter;
private createHistogram;
private create;
/**
* Publishes metrics to the workers metrics API
* This function is a no-op in test and wrangler environements
*/
publish(): Promise<void>;
}
export {};
48 changes: 48 additions & 0 deletions dist/errors.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Labels } from 'promjs';
import { Context } from './context';
import { JSONResponse } from './utils/jsonResponse';
export declare function handleError(ctx: Context, error: Error, labels?: Labels): Promise<JSONResponse>;
export declare class HTTPError extends Error {
status: number;
constructor(message?: string, status?: number);
}
export declare class MethodNotAllowedError extends HTTPError {
static CODE: string;
code: string;
constructor(message?: string);
}
export declare class PageNotFoundError extends HTTPError {
static CODE: string;
code: string;
constructor(message?: string);
}
export declare class HeaderNotDefinedError extends HTTPError {
static CODE: string;
code: string;
constructor(message?: string);
}
export declare class InternalCacheError extends HTTPError {
static CODE: string;
code: string;
constructor(message?: string);
}
export declare class NotImplementedError extends HTTPError {
static CODE: string;
code: string;
constructor(message?: string);
}
export declare class UnreachableError extends HTTPError {
static CODE: string;
code: string;
constructor(message?: string);
}
export declare class InvalidTokenTypeError extends HTTPError {
static CODE: string;
code: string;
constructor(message?: string);
}
export declare class BadTokenKeyRequestedError extends HTTPError {
static CODE: string;
code: string;
constructor(message?: string);
}
Loading