mirror of
https://codeberg.org/keyoxide/doipjs.git
synced 2024-12-22 14:39:28 -07:00
feat: tweaks to src, use new classes and enums
This commit is contained in:
parent
149ac6f71e
commit
00d646e2b2
6 changed files with 130 additions and 47 deletions
10
src/asp.js
10
src/asp.js
|
@ -19,6 +19,7 @@ import { base32, base64url } from 'rfc4648'
|
|||
import { Claim } from './claim.js'
|
||||
import { Persona } from './persona.js'
|
||||
import { Profile } from './profile.js'
|
||||
import { ProfileType } from './enums.js'
|
||||
|
||||
const SupportedCryptoAlg = ['EdDSA', 'ES256', 'ES256K', 'ES384', 'ES512']
|
||||
|
||||
|
@ -129,9 +130,12 @@ export async function parseProfileJws (profileJws, uri) {
|
|||
|
||||
const profileClaimsParsed = profileClaims.map(x => new Claim(x, uri))
|
||||
|
||||
const pe = new Persona(profileName, profileDescription || '', profileClaimsParsed)
|
||||
const pr = new Profile([pe])
|
||||
pr.primaryPersona = 0
|
||||
const pe = new Persona(profileName, profileClaimsParsed)
|
||||
if (profileDescription) {
|
||||
pe.setDescription(profileDescription)
|
||||
}
|
||||
|
||||
const pr = new Profile(ProfileType.ASP, uri, [pe])
|
||||
|
||||
return pr
|
||||
}
|
||||
|
|
73
src/enums.js
73
src/enums.js
|
@ -75,9 +75,9 @@ export const EntityEncodingFormat = {
|
|||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
export const ProofAccess = {
|
||||
export const ProofAccessRestriction = {
|
||||
/** Any HTTP request will work */
|
||||
GENERIC: 'generic',
|
||||
NONE: 'none',
|
||||
/** CORS requests are denied */
|
||||
NOCORS: 'nocors',
|
||||
/** HTTP requests must contain API or access tokens */
|
||||
|
@ -127,13 +127,72 @@ export const ClaimRelation = {
|
|||
/**
|
||||
* Status of the Claim instance
|
||||
* @readonly
|
||||
* @enum {string}
|
||||
* @enum {number}
|
||||
*/
|
||||
export const ClaimStatus = {
|
||||
/** Claim has been initialized */
|
||||
INIT: 'init',
|
||||
INIT: 100,
|
||||
/** Claim has matched its URI to candidate claim definitions */
|
||||
MATCHED: 'matched',
|
||||
/** Claim has verified one or multiple candidate claim definitions */
|
||||
VERIFIED: 'verified'
|
||||
MATCHED: 101,
|
||||
/** Claim was successfully verified */
|
||||
VERIFIED: 200,
|
||||
/** Claim was successfully verified using proxied data */
|
||||
VERIFIED_VIA_PROXY: 201,
|
||||
/** Unknown matching error */
|
||||
MATCHING_ERROR: 300,
|
||||
/** No matched service providers */
|
||||
NO_MATCHES: 301,
|
||||
/** Unknown matching error */
|
||||
VERIFICATION_ERROR: 400,
|
||||
/** No proof found in data returned by service providers */
|
||||
NO_PROOF_FOUND: 401
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile type
|
||||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
export const ProfileType = {
|
||||
/** ASP profile */
|
||||
ASP: 'asp',
|
||||
/** OpenPGP profile */
|
||||
OPENPGP: 'openpgp'
|
||||
}
|
||||
|
||||
/**
|
||||
* Public key type
|
||||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
export const PublicKeyType = {
|
||||
EDDSA: 'eddsa',
|
||||
ES256: 'es256',
|
||||
OPENPGP: 'openpgp',
|
||||
NONE: 'none'
|
||||
}
|
||||
|
||||
/**
|
||||
* Public key format
|
||||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
export const PublicKeyEncoding = {
|
||||
PEM: 'pem',
|
||||
JWK: 'jwk',
|
||||
ARMORED_PGP: 'armored_pgp',
|
||||
NONE: 'none'
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to fetch the public key
|
||||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
export const PublicKeyFetchMethod = {
|
||||
ASPE: 'aspe',
|
||||
HKP: 'hkp',
|
||||
WKD: 'wkd',
|
||||
HTTP: 'http',
|
||||
NONE: 'none'
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ export { Profile } from './profile.js'
|
|||
export { Persona } from './persona.js'
|
||||
export { Claim } from './claim.js'
|
||||
export { ServiceProvider } from './serviceProvider.js'
|
||||
export * as ServiceProviderDefinitions from './serviceProviders/index.js'
|
||||
export * as proofs from './proofs.js'
|
||||
export * as openpgp from './openpgp.js'
|
||||
export * as asp from './asp.js'
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
import { isNode } from 'browser-or-node'
|
||||
import * as fetcher from './fetcher/index.js'
|
||||
import { generateProxyURL } from './utils.js'
|
||||
import { Fetcher, ProxyPolicy, ProofAccess } from './enums.js'
|
||||
import { ProxyPolicy, ProofAccessRestriction } from './enums.js'
|
||||
|
||||
/**
|
||||
* @module proofs
|
||||
|
@ -29,20 +29,11 @@ import { Fetcher, ProxyPolicy, ProofAccess } from './enums.js'
|
|||
* choose the right approach to fetch the proof. An error will be thrown if no
|
||||
* approach is possible.
|
||||
* @async
|
||||
* @param {object} data - Data from a claim definition
|
||||
* @param {import('./serviceProvider.js').ServiceProvider} data - Data from a claim definition
|
||||
* @param {object} opts - Options to enable the request
|
||||
* @returns {Promise<object|string>}
|
||||
*/
|
||||
export async function fetch (data, opts) {
|
||||
switch (data.proof.request.fetcher) {
|
||||
case Fetcher.HTTP:
|
||||
data.proof.request.data.format = data.proof.request.format
|
||||
break
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
return handleNodeRequests(data, opts)
|
||||
}
|
||||
|
@ -50,6 +41,11 @@ export async function fetch (data, opts) {
|
|||
return handleBrowserRequests(data, opts)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./serviceProvider.js').ServiceProvider} data - Data from a claim definition
|
||||
* @param {object} opts - Options to enable the request
|
||||
* @returns {Promise<object|string>}
|
||||
*/
|
||||
const handleBrowserRequests = (data, opts) => {
|
||||
switch (opts.proxy.policy) {
|
||||
case ProxyPolicy.ALWAYS:
|
||||
|
@ -57,11 +53,11 @@ const handleBrowserRequests = (data, opts) => {
|
|||
|
||||
case ProxyPolicy.NEVER:
|
||||
switch (data.proof.request.access) {
|
||||
case ProofAccess.GENERIC:
|
||||
case ProofAccess.GRANTED:
|
||||
case ProofAccessRestriction.NONE:
|
||||
case ProofAccessRestriction.GRANTED:
|
||||
return createDefaultRequestPromise(data, opts)
|
||||
case ProofAccess.NOCORS:
|
||||
case ProofAccess.SERVER:
|
||||
case ProofAccessRestriction.NOCORS:
|
||||
case ProofAccessRestriction.SERVER:
|
||||
throw new Error(
|
||||
'Impossible to fetch proof (bad combination of service access and proxy policy)'
|
||||
)
|
||||
|
@ -71,13 +67,13 @@ const handleBrowserRequests = (data, opts) => {
|
|||
|
||||
case ProxyPolicy.ADAPTIVE:
|
||||
switch (data.proof.request.access) {
|
||||
case ProofAccess.GENERIC:
|
||||
case ProofAccessRestriction.NONE:
|
||||
return createFallbackRequestPromise(data, opts)
|
||||
case ProofAccess.NOCORS:
|
||||
case ProofAccessRestriction.NOCORS:
|
||||
return createProxyRequestPromise(data, opts)
|
||||
case ProofAccess.GRANTED:
|
||||
case ProofAccessRestriction.GRANTED:
|
||||
return createFallbackRequestPromise(data, opts)
|
||||
case ProofAccess.SERVER:
|
||||
case ProofAccessRestriction.SERVER:
|
||||
return createProxyRequestPromise(data, opts)
|
||||
default:
|
||||
throw new Error('Invalid proof access value')
|
||||
|
@ -88,6 +84,11 @@ const handleBrowserRequests = (data, opts) => {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./serviceProvider.js').ServiceProvider} data - Data from a claim definition
|
||||
* @param {object} opts - Options to enable the request
|
||||
* @returns {Promise<object|string>}
|
||||
*/
|
||||
const handleNodeRequests = (data, opts) => {
|
||||
switch (opts.proxy.policy) {
|
||||
case ProxyPolicy.ALWAYS:
|
||||
|
@ -104,13 +105,21 @@ const handleNodeRequests = (data, opts) => {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./serviceProvider.js').ServiceProvider} data - Data from a claim definition
|
||||
* @param {object} opts - Options to enable the request
|
||||
* @returns {Promise<object|string>}
|
||||
*/
|
||||
const createDefaultRequestPromise = (data, opts) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
fetcher[data.proof.request.fetcher]
|
||||
if (!(data.proof.request.protocol in fetcher)) {
|
||||
reject(new Error(`fetcher for ${data.proof.request.protocol} not found`))
|
||||
}
|
||||
fetcher[data.proof.request.protocol]
|
||||
.fn(data.proof.request.data, opts)
|
||||
.then((res) => {
|
||||
return resolve({
|
||||
fetcher: data.proof.request.fetcher,
|
||||
protocol: data.proof.request.protocol,
|
||||
data,
|
||||
viaProxy: false,
|
||||
result: res
|
||||
|
@ -122,12 +131,17 @@ const createDefaultRequestPromise = (data, opts) => {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./serviceProvider.js').ServiceProvider} data - Data from a claim definition
|
||||
* @param {object} opts - Options to enable the request
|
||||
* @returns {Promise<object|string>}
|
||||
*/
|
||||
const createProxyRequestPromise = (data, opts) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let proxyUrl
|
||||
try {
|
||||
proxyUrl = generateProxyURL(
|
||||
data.proof.request.fetcher,
|
||||
data.proof.request.protocol,
|
||||
data.proof.request.data,
|
||||
opts
|
||||
)
|
||||
|
@ -138,13 +152,13 @@ const createProxyRequestPromise = (data, opts) => {
|
|||
const requestData = {
|
||||
url: proxyUrl,
|
||||
format: data.proof.request.format,
|
||||
fetcherTimeout: fetcher[data.proof.request.fetcher].timeout
|
||||
fetcherTimeout: fetcher[data.proof.request.protocol].timeout
|
||||
}
|
||||
fetcher.http
|
||||
.fn(requestData, opts)
|
||||
.then((res) => {
|
||||
return resolve({
|
||||
fetcher: 'http',
|
||||
protocol: 'http',
|
||||
data,
|
||||
viaProxy: true,
|
||||
result: res
|
||||
|
@ -156,6 +170,11 @@ const createProxyRequestPromise = (data, opts) => {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./serviceProvider.js').ServiceProvider} data - Data from a claim definition
|
||||
* @param {object} opts - Options to enable the request
|
||||
* @returns {Promise<object|string>}
|
||||
*/
|
||||
const createFallbackRequestPromise = (data, opts) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
createDefaultRequestPromise(data, opts)
|
||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
import { readCleartextMessage, verify } from 'openpgp'
|
||||
import { Claim } from './claim.js'
|
||||
import { fetchURI } from './keys.js'
|
||||
import { fetchURI } from './openpgp.js'
|
||||
|
||||
/**
|
||||
* @module signatures
|
||||
|
@ -89,7 +89,7 @@ export async function process (signature) {
|
|||
if (sigKeys.length > 0) {
|
||||
try {
|
||||
result.key.uri = sigKeys[0]
|
||||
result.key.data = await fetchURI(result.key.uri)
|
||||
result.key.data = (await fetchURI(result.key.uri)).publicKey.key
|
||||
result.key.fetchMethod = result.key.uri.split(':')[0]
|
||||
} catch (e) {}
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ export async function process (signature) {
|
|||
if (!result.key.data && signersUserID) {
|
||||
try {
|
||||
result.key.uri = `wkd:${signersUserID}`
|
||||
result.key.data = await fetchURI(result.key.uri)
|
||||
result.key.data = (await fetchURI(result.key.uri)).publicKey.key
|
||||
result.key.fetchMethod = 'wkd'
|
||||
} catch (e) {}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ export async function process (signature) {
|
|||
try {
|
||||
const match = preferredKeyServer.match(/^(.*:\/\/)?([^/]*)(?:\/)?$/i)
|
||||
result.key.uri = `hkp:${match[2]}:${issuerKeyID || signersUserID}`
|
||||
result.key.data = await fetchURI(result.key.uri)
|
||||
result.key.data = (await fetchURI(result.key.uri)).publicKey.key
|
||||
result.key.fetchMethod = 'hkp'
|
||||
} catch (e) {
|
||||
throw new Error('Public key not found')
|
||||
|
|
|
@ -176,7 +176,7 @@ const containsProof = async (data, params) => {
|
|||
/**
|
||||
* @function
|
||||
* @param {any} proofData
|
||||
* @param {string} checkPath
|
||||
* @param {string[]} checkPath
|
||||
* @param {object} params
|
||||
* @param {string} params.target
|
||||
* @param {string} params.claimFormat
|
||||
|
@ -231,9 +231,9 @@ const runJSON = async (proofData, checkPath, params) => {
|
|||
/**
|
||||
* Run the verification by finding the formatted fingerprint in the proof
|
||||
* @async
|
||||
* @param {object} proofData - The proof data
|
||||
* @param {object} claimData - The claim data
|
||||
* @param {string} fingerprint - The fingerprint
|
||||
* @param {object} proofData - The proof data
|
||||
* @param {import('./serviceProvider.js').ServiceProvider} claimData - The claim data
|
||||
* @param {string} fingerprint - The fingerprint
|
||||
* @returns {Promise<object>}
|
||||
*/
|
||||
export async function run (proofData, claimData, fingerprint) {
|
||||
|
@ -243,10 +243,10 @@ export async function run (proofData, claimData, fingerprint) {
|
|||
errors: []
|
||||
}
|
||||
|
||||
switch (claimData.proof.request.format) {
|
||||
switch (claimData.proof.response.format) {
|
||||
case ProofFormat.JSON:
|
||||
for (let index = 0; index < claimData.claim.length; index++) {
|
||||
const claimMethod = claimData.claim[index]
|
||||
for (let index = 0; index < claimData.proof.target.length; index++) {
|
||||
const claimMethod = claimData.proof.target[index]
|
||||
try {
|
||||
res.result = res.result || await runJSON(
|
||||
proofData,
|
||||
|
@ -265,8 +265,8 @@ export async function run (proofData, claimData, fingerprint) {
|
|||
res.completed = true
|
||||
break
|
||||
case ProofFormat.TEXT:
|
||||
for (let index = 0; index < claimData.claim.length; index++) {
|
||||
const claimMethod = claimData.claim[index]
|
||||
for (let index = 0; index < claimData.proof.target.length; index++) {
|
||||
const claimMethod = claimData.proof.target[index]
|
||||
try {
|
||||
res.result = res.result || await containsProof(
|
||||
proofData,
|
||||
|
|
Loading…
Reference in a new issue