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

fix: make tests use did:web everywhere #397

Merged
merged 1 commit into from
Jan 27, 2023
Merged
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
2 changes: 1 addition & 1 deletion packages/access-api/src/bindings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface Env {
* publicly advertised decentralized identifier of the running api service
* * this may be used to filter incoming ucanto invocations
*/
DID: string
DID: `did:web:${string}`
// URLs to upload-api so we proxy invocations to it
UPLOAD_API_URL: string
UPLOAD_API_URL_STAGING: string
Expand Down
45 changes: 6 additions & 39 deletions packages/access-api/src/config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Signer } from '@ucanto/principal/ed25519'
// @ts-ignore
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use ts-expect-error instead? It is easier to flag when it gets fixed

// eslint-disable-next-line no-unused-vars
import * as UCAN from '@ucanto/interface'
import { DID } from '@ucanto/core'
Expand All @@ -15,6 +15,7 @@ export function loadConfig(env) {

/** @type {Array<keyof env>} */
const required = [
'DID',
'ENV',
'DEBUG',
'PRIVATE_KEY',
Expand All @@ -34,9 +35,6 @@ export function loadConfig(env) {
}
}

const DID = env.DID
const PRIVATE_KEY = vars.PRIVATE_KEY
const signer = configureSigner({ DID, PRIVATE_KEY })
return {
DEBUG: boolValue(vars.DEBUG),
ENV: parseRuntimeEnv(vars.ENV),
Expand All @@ -56,8 +54,11 @@ export function loadConfig(env) {
// eslint-disable-next-line no-undef
COMMITHASH: ACCOUNT_COMMITHASH,

signer,
PRIVATE_KEY: vars.PRIVATE_KEY,
DID: DID.parse(vars.DID).did(),

UPLOAD_API_URL: env.UPLOAD_API_URL,
UPLOAD_API_URL_STAGING: env.UPLOAD_API_URL_STAGING,
// bindings
METRICS:
/** @type {import("./bindings").AnalyticsEngine} */ (
Expand All @@ -66,9 +67,6 @@ export function loadConfig(env) {
SPACES: env.SPACES,
VALIDATIONS: env.VALIDATIONS,
DB: /** @type {D1Database} */ (env.__D1_BETA__),

UPLOAD_API_URL: env.UPLOAD_API_URL,
UPLOAD_API_URL_STAGING: env.UPLOAD_API_URL_STAGING,
}
}

Expand Down Expand Up @@ -117,34 +115,3 @@ export function createAnalyticsEngine() {
_store: store,
}
}

/**
* Given a config, return a ucanto Signer object representing the service
*
* @param {object} config
* @param {string} config.PRIVATE_KEY - multiformats private key of primary signing key
* @param {string} [config.DID] - public DID for the service (did:key:... derived from PRIVATE_KEY if not set)
* @returns {Signer.Signer}
*/
export function configureSigner(config) {
const signer = Signer.parse(config.PRIVATE_KEY)
if (config.DID) {
return signer.withDID(DID.parse(config.DID).did())
}
return signer
}

/**
* @template {UCAN.DID} ConfigDID
* @template {UCAN.SigAlg} [Alg=UCAN.SigAlg]
* @param {object} config
* @param {ConfigDID} [config.DID] - public DID for the service
* @param {import('@ucanto/interface').Verifier<ConfigDID,Alg>} verifier
* @returns {import('@ucanto/interface').Verifier<ConfigDID,Alg>}
*/
export function configureVerifier(config, verifier) {
if (config.DID) {
return verifier.withDID(DID.parse(config.DID).did())
}
return verifier
}
7 changes: 6 additions & 1 deletion packages/access-api/src/utils/context.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Logging } from '@web3-storage/worker-utils/logging'
import Toucan from 'toucan-js'
import { Signer } from '@ucanto/principal/ed25519'
import pkg from '../../package.json'
import { loadConfig } from '../config.js'
import { Spaces } from '../models/spaces.js'
Expand All @@ -16,6 +17,8 @@ import { Email } from './email.js'
*/
export function getContext(request, env, ctx) {
const config = loadConfig(env)

// Sentry
const sentry = new Toucan({
context: ctx,
request,
Expand All @@ -30,6 +33,8 @@ export function getContext(request, env, ctx) {
release: config.VERSION,
pkg,
})

// Logging
const log = new Logging(request, ctx, {
token: config.LOGTAIL_TOKEN,
debug: config.DEBUG,
Expand All @@ -42,7 +47,7 @@ export function getContext(request, env, ctx) {
const url = new URL(request.url)
return {
log,
signer: config.signer,
signer: Signer.parse(config.PRIVATE_KEY).withDID(config.DID),
config,
url,
models: {
Expand Down
61 changes: 0 additions & 61 deletions packages/access-api/test/config.test.js

This file was deleted.

30 changes: 11 additions & 19 deletions packages/access-api/test/helpers/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { Miniflare, Log, LogLevel } from 'miniflare'
import path from 'path'
import { fileURLToPath } from 'url'
import { migrate } from '../../scripts/migrate.js'
import { configureSigner } from '../../src/config.js'

const __dirname = path.dirname(fileURLToPath(import.meta.url))

Expand All @@ -21,14 +20,14 @@ dotenv.config({
/**
* Given a map of environment vars, return a map of bindings that can be passed with access-api worker invocations.
*
* @param {{ [key: string]: string | undefined }} env - environment variables
* @param {any} env - environment variables
* @returns {AccessApiBindings} - env bindings expected by access-api worker objects
*/
function createBindings(env) {
return {
ENV: 'test',
DEBUG: 'false',
DID: env.DID || '',
DID: env.DID || 'did:web:test.web3.storage',
PRIVATE_KEY: env.PRIVATE_KEY || '',
POSTMARK_TOKEN: env.POSTMARK_TOKEN || '',
SENTRY_DSN: env.SENTRY_DSN || '',
Expand All @@ -40,23 +39,16 @@ function createBindings(env) {
}

/**
* Good default bindings useful for tests - configured via process.env
* @param {Partial<AccessApiBindings>} env - environment variables to use when configuring access-api. Defaults to process.env.
*/
export const bindings = createBindings(process.env)

export const serviceAuthority = Signer.parse(bindings.PRIVATE_KEY)

/**
* @param {object} [options]
* @param {Record<string,string|undefined>} options.environment - environment variables to use when configuring access-api. Defaults to process.env.
*/
export async function context(options) {
const environment = options?.environment || process.env
const principal = await Signer.generate()
export async function context(env = {}) {
const bindings = createBindings({
...environment,
...process.env,
...env,
})
const servicePrincipal = configureSigner(bindings)
const servicePrincipal = Signer.parse(bindings.PRIVATE_KEY).withDID(
bindings.DID
)
const mf = new Miniflare({
packagePath: true,
wranglerConfigPath: true,
Expand All @@ -80,8 +72,8 @@ export async function context(options) {
fetch: mf.dispatchFetch.bind(mf),
url: new URL('http://localhost:8787'),
}),
service: Signer.parse(bindings.PRIVATE_KEY),
issuer: principal,
service: servicePrincipal,
issuer: await Signer.generate(),
d1: db,
}
}
Expand Down
30 changes: 10 additions & 20 deletions packages/access-api/test/store-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,16 @@ describe('proxy store/list invocations to upload-api', function () {
// if this is set, it's to inject in the actual private key used by web3StorageDid.
// and if it's present, the assertions will expect no error from the proxy or upstream
const privateKeyFromEnv = process.env.WEB3_STORAGE_PRIVATE_KEY
const {
issuer,
service: serviceSigner,
conn,
} = await context({
environment: {
...process.env,
// this emulates the configuration for deployed environments,
// which will allow the access-api ucanto server to accept
// invocations where aud=web3storageDid
DID: web3storageDid,
PRIVATE_KEY: privateKeyFromEnv ?? process.env.PRIVATE_KEY,
UPLOAD_API_URL: mockUpstreamUrl.toString(),
UPLOAD_API_URL_STAGING: mockUpstreamUrl.toString(),
},
const { issuer, service, conn } = await context({
// this emulates the configuration for deployed environments,
// which will allow the access-api ucanto server to accept
// invocations where aud=web3storageDid
DID: web3storageDid,
// @ts-ignore
PRIVATE_KEY: privateKeyFromEnv ?? process.env.PRIVATE_KEY,
UPLOAD_API_URL: mockUpstreamUrl.toString(),
UPLOAD_API_URL_STAGING: mockUpstreamUrl.toString(),
})
const service = serviceSigner.withDID(web3storageDid)
const spaceCreation = await createSpace(
issuer,
service,
Expand Down Expand Up @@ -98,10 +91,7 @@ describe('proxy store/list invocations to upload-api', function () {
Array.from({ length: 3 }).map(() => ed25519.Signer.generate())
)
const { service: serviceSigner, conn } = await context({
environment: {
...process.env,
UPLOAD_API_URL: mockUpstreamUrl.toString(),
},
UPLOAD_API_URL: mockUpstreamUrl.toString(),
})
const service = process.env.DID
? serviceSigner.withDID(ucanto.DID.parse(process.env.DID).did())
Expand Down
6 changes: 2 additions & 4 deletions packages/access-api/test/ucan.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,8 @@ describe('ucan', function () {
test('should support ucan invoking to a did:web aud', async function () {
const serviceDidWeb = 'did:web:example.com'
const { mf, issuer, service } = await context({
environment: {
...process.env,
DID: serviceDidWeb,
},
...process.env,
DID: serviceDidWeb,
})
const ucan = await UCAN.issue({
issuer,
Expand Down
8 changes: 3 additions & 5 deletions packages/access-api/test/upload-api-proxy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,9 @@ function testCanProxyInvocation(can) {
})
const mockUpstreamUrl = serverLocalUrl(mockUpstreamHttp.address())
const { issuer, conn } = await context({
environment: {
...process.env,
UPLOAD_API_URL: mockUpstreamUrl.toString(),
DID: upstreamPrincipal.did(),
},
UPLOAD_API_URL: mockUpstreamUrl.toString(),
// @ts-expect-error This expects did:web
DID: upstreamPrincipal.did(),
})
/** @type {Ucanto.ConnectionView<any>} */
const connection = conn
Expand Down