fix: fix linting issues

This commit is contained in:
Yarmo Mackenbach 2023-07-13 11:19:48 +02:00
parent 2760adf5f8
commit b8114bad9e
No known key found for this signature in database
GPG key ID: 3C57D093219103A3
4 changed files with 256 additions and 278 deletions

View file

@ -37,7 +37,7 @@ import { claimSchema, personaSchema, profileSchema, serviceProviderSchema } from
dotenv.config() dotenv.config()
const router = express.Router() const router = express.Router()
const ajv = new Ajv({ const ajv = new Ajv({
schemas: [profileSchema, personaSchema, claimSchema, serviceProviderSchema] schemas: [profileSchema, personaSchema, claimSchema, serviceProviderSchema]
}) })
@ -157,7 +157,7 @@ router.get('/verify',
return return
} }
let profile = Claim.fromJson(req.query.data) const profile = Claim.fromJson(req.query.data)
// Do verification // Do verification
let data = await doVerification(profile) let data = await doVerification(profile)

View file

@ -28,336 +28,335 @@ if any, to sign a "copyright disclaimer" for the program, if necessary. For
more information on this, and how to apply and follow the GNU AGPL, see <https://www.gnu.org/licenses/>. more information on this, and how to apply and follow the GNU AGPL, see <https://www.gnu.org/licenses/>.
*/ */
export const profileSchema = { export const profileSchema = {
"$schema": "https://json-schema.org/draft/2020-12/schema", $schema: 'https://json-schema.org/draft/2020-12/schema',
"$id": "https://spec.keyoxide.org/2/profile.schema.json", $id: 'https://spec.keyoxide.org/2/profile.schema.json',
"title": "Profile", title: 'Profile',
"description": "Keyoxide profile with personas", description: 'Keyoxide profile with personas',
"type": "object", type: 'object',
"properties": { properties: {
"profileVersion": { profileVersion: {
"description": "The version of the profile", description: 'The version of the profile',
"type": "integer" type: 'integer'
}, },
"profileType": { profileType: {
"description": "The type of the profile [openpgp, asp]", description: 'The type of the profile [openpgp, asp]',
"type": "string" type: 'string'
}, },
"identifier": { identifier: {
"description": "Identifier of the profile (email, fingerprint, URI)", description: 'Identifier of the profile (email, fingerprint, URI)',
"type": "string" type: 'string'
}, },
"personas": { personas: {
"description": "The personas inside the profile", description: 'The personas inside the profile',
"type": "array", type: 'array',
"items": { items: {
"$ref": "https://spec.keyoxide.org/2/persona.schema.json" $ref: 'https://spec.keyoxide.org/2/persona.schema.json'
}, },
"minItems": 1, minItems: 1,
"uniqueItems": true uniqueItems: true
}, },
"primaryPersonaIndex": { primaryPersonaIndex: {
"description": "The index of the primary persona", description: 'The index of the primary persona',
"type": "integer" type: 'integer'
}, },
"publicKey": { publicKey: {
"description": "The cryptographic key associated with the profile", description: 'The cryptographic key associated with the profile',
"type": "object", type: 'object',
"properties": { properties: {
"keyType": { keyType: {
"description": "The type of cryptographic key [eddsa, es256, openpgp, none]", description: 'The type of cryptographic key [eddsa, es256, openpgp, none]',
"type": "string" type: 'string'
}, },
"encoding": { encoding: {
"description": "The encoding of the cryptographic key [pem, jwk, armored_pgp, none]", description: 'The encoding of the cryptographic key [pem, jwk, armored_pgp, none]',
"type": "string" type: 'string'
}, },
"encodedKey": { encodedKey: {
"description": "The encoded cryptographic key (PEM, stringified JWK, ...)", description: 'The encoded cryptographic key (PEM, stringified JWK, ...)',
"type": ["string", "null"] type: ['string', 'null']
}, },
"fetch": { fetch: {
"description": "Details on how to fetch the public key", description: 'Details on how to fetch the public key',
"type": "object", type: 'object',
"properties": { properties: {
"method": { method: {
"description": "The method to fetch the key [aspe, hkp, wkd, http, none]", description: 'The method to fetch the key [aspe, hkp, wkd, http, none]',
"type": "string" type: 'string'
}, },
"query": { query: {
"description": "The query to fetch the key", description: 'The query to fetch the key',
"type": ["string", "null"] type: ['string', 'null']
}, },
"resolvedUrl": { resolvedUrl: {
"description": "The URL the method eventually resolved to", description: 'The URL the method eventually resolved to',
"type": ["string", "null"] type: ['string', 'null']
} }
} }
} }
}, },
"required": [ required: [
"keyType", 'keyType',
"fetch" 'fetch'
] ]
}, },
"verifiers": { verifiers: {
"description": "A list of links to verifiers", description: 'A list of links to verifiers',
"type": "array", type: 'array',
"items": { items: {
"type": "object", type: 'object',
"properties": { properties: {
"name": { name: {
"description": "Name of the verifier site", description: 'Name of the verifier site',
"type": "string" type: 'string'
}, },
"url": { url: {
"description": "URL to the profile page on the verifier site", description: 'URL to the profile page on the verifier site',
"type": "string" type: 'string'
} }
} }
}, },
"uniqueItems": true uniqueItems: true
} }
}, },
"required": [ required: [
"profileVersion", 'profileVersion',
"profileType", 'profileType',
"identifier", 'identifier',
"personas", 'personas',
"primaryPersonaIndex", 'primaryPersonaIndex',
"publicKey", 'publicKey',
"verifiers" 'verifiers'
], ],
"additionalProperties": false additionalProperties: false
} }
export const personaSchema = { export const personaSchema = {
"$schema": "https://json-schema.org/draft/2020-12/schema", $schema: 'https://json-schema.org/draft/2020-12/schema',
"$id": "https://spec.keyoxide.org/2/persona.schema.json", $id: 'https://spec.keyoxide.org/2/persona.schema.json',
"title": "Profile", title: 'Profile',
"description": "Keyoxide persona with identity claims", description: 'Keyoxide persona with identity claims',
"type": "object", type: 'object',
"properties": { properties: {
"identifier": { identifier: {
"description": "Identifier of the persona", description: 'Identifier of the persona',
"type": ["string", "null"] type: ['string', 'null']
}, },
"name": { name: {
"description": "Name of the persona", description: 'Name of the persona',
"type": "string" type: 'string'
}, },
"email": { email: {
"description": "Email address of the persona", description: 'Email address of the persona',
"type": ["string", "null"] type: ['string', 'null']
}, },
"description": { description: {
"description": "Description of the persona", description: 'Description of the persona',
"type": ["string", "null"] type: ['string', 'null']
}, },
"avatarUrl": { avatarUrl: {
"description": "URL to an avatar image", description: 'URL to an avatar image',
"type": ["string", "null"] type: ['string', 'null']
}, },
"isRevoked": { isRevoked: {
"type": "boolean" type: 'boolean'
}, },
"claims": { claims: {
"description": "A list of identity claims", description: 'A list of identity claims',
"type": "array", type: 'array',
"items": { items: {
"$ref": "https://spec.keyoxide.org/2/claim.schema.json" $ref: 'https://spec.keyoxide.org/2/claim.schema.json'
}, },
"uniqueItems": true uniqueItems: true
} }
}, },
"required": [ required: [
"name", 'name',
"claims" 'claims'
], ],
"additionalProperties": false additionalProperties: false
} }
export const claimSchema = { export const claimSchema = {
"$schema": "https://json-schema.org/draft/2020-12/schema", $schema: 'https://json-schema.org/draft/2020-12/schema',
"$id": "https://spec.keyoxide.org/2/claim.schema.json", $id: 'https://spec.keyoxide.org/2/claim.schema.json',
"title": "Identity claim", title: 'Identity claim',
"description": "Verifiable online identity claim", description: 'Verifiable online identity claim',
"type": "object", type: 'object',
"properties": { properties: {
"claimVersion": { claimVersion: {
"description": "The version of the claim", description: 'The version of the claim',
"type": "integer" type: 'integer'
}, },
"uri": { uri: {
"description": "The claim URI", description: 'The claim URI',
"type": "string" type: 'string'
}, },
"proofs": { proofs: {
"description": "The proofs that would verify the claim", description: 'The proofs that would verify the claim',
"type": "array", type: 'array',
"items": { items: {
"type": "string" type: 'string'
}, },
"minItems": 1, minItems: 1,
"uniqueItems": true uniqueItems: true
}, },
"matches": { matches: {
"description": "Service providers matched to the claim", description: 'Service providers matched to the claim',
"type": "array", type: 'array',
"items": { items: {
"$ref": "https://spec.keyoxide.org/2/serviceprovider.schema.json" $ref: 'https://spec.keyoxide.org/2/serviceprovider.schema.json'
}, },
"uniqueItems": true uniqueItems: true
}, },
"status": { status: {
"type": "integer", type: 'integer',
"description": "Claim status code" description: 'Claim status code'
}, },
"display": { display: {
"type": "object", type: 'object',
"properties": { properties: {
"name": { name: {
"type": "string", type: 'string',
"description": "Account name to display in the user interface" description: 'Account name to display in the user interface'
}, },
"url": { url: {
"type": ["string", "null"], type: ['string', 'null'],
"description": "URL to link to in the user interface" description: 'URL to link to in the user interface'
}, },
"serviceProviderName": { serviceProviderName: {
"type": ["string", "null"], type: ['string', 'null'],
"description": "Name of the service provider to display in the user interface" description: 'Name of the service provider to display in the user interface'
} }
} }
} }
}, },
"required": [ required: [
"claimVersion", 'claimVersion',
"uri", 'uri',
"proofs", 'proofs',
"status", 'status',
"display" 'display'
], ],
"additionalProperties": false additionalProperties: false
} }
export const serviceProviderSchema = { export const serviceProviderSchema = {
"$schema": "https://json-schema.org/draft/2020-12/schema", $schema: 'https://json-schema.org/draft/2020-12/schema',
"$id": "https://spec.keyoxide.org/2/serviceprovider.schema.json", $id: 'https://spec.keyoxide.org/2/serviceprovider.schema.json',
"title": "Service provider", title: 'Service provider',
"description": "A service provider that can be matched to identity claims", description: 'A service provider that can be matched to identity claims',
"type": "object", type: 'object',
"properties": { properties: {
"about": { about: {
"description": "Details about the service provider", description: 'Details about the service provider',
"type": "object", type: 'object',
"properties": { properties: {
"name": { name: {
"description": "Full name of the service provider", description: 'Full name of the service provider',
"type": "string" type: 'string'
}, },
"id": { id: {
"description": "Identifier of the service provider (no whitespace or symbols, lowercase)", description: 'Identifier of the service provider (no whitespace or symbols, lowercase)',
"type": "string" type: 'string'
}, },
"homepage": { homepage: {
"description": "URL to the homepage of the service provider", description: 'URL to the homepage of the service provider',
"type": ["string", "null"] type: ['string', 'null']
} }
} }
}, },
"profile": { profile: {
"description": "What the profile would look like if the match is correct", description: 'What the profile would look like if the match is correct',
"type": "object", type: 'object',
"properties": { properties: {
"display": { display: {
"description": "Profile name to be displayed", description: 'Profile name to be displayed',
"type": "string" type: 'string'
}, },
"uri": { uri: {
"description": "URI or URL for public access to the profile", description: 'URI or URL for public access to the profile',
"type": "string" type: 'string'
}, },
"qr": { qr: {
"description": "URI or URL associated with the profile usually served as a QR code", description: 'URI or URL associated with the profile usually served as a QR code',
"type": ["string", "null"] type: ['string', 'null']
} }
} }
}, },
"claim": { claim: {
"description": "Details from the claim matching process", description: 'Details from the claim matching process',
"type": "object", type: 'object',
"properties": { properties: {
"uriRegularExpression": { uriRegularExpression: {
"description": "Regular expression used to parse the URI", description: 'Regular expression used to parse the URI',
"type": "string" type: 'string'
}, },
"uriIsAmbiguous": { uriIsAmbiguous: {
"description": "Whether this match automatically excludes other matches", description: 'Whether this match automatically excludes other matches',
"type": "boolean" type: 'boolean'
} }
} }
}, },
"proof": { proof: {
"description": "Information for the proof verification process", description: 'Information for the proof verification process',
"type": "object", type: 'object',
"properties": { properties: {
"request": { request: {
"description": "Details to request the potential proof", description: 'Details to request the potential proof',
"type": "object", type: 'object',
"properties": { properties: {
"uri": { uri: {
"description": "Location of the proof", description: 'Location of the proof',
"type": ["string", "null"] type: ['string', 'null']
}, },
"accessRestriction": { accessRestriction: {
"description": "Type of access restriction [none, nocors, granted, server]", description: 'Type of access restriction [none, nocors, granted, server]',
"type": "string" type: 'string'
}, },
"fetcher": { fetcher: {
"description": "Name of the fetcher to use", description: 'Name of the fetcher to use',
"type": "string" type: 'string'
}, },
"data": { data: {
"description": "Data needed by the fetcher or proxy to request the proof", description: 'Data needed by the fetcher or proxy to request the proof',
"type": "object", type: 'object',
"additionalProperties": true additionalProperties: true
} }
} }
}, },
"response": { response: {
"description": "Details about the expected response", description: 'Details about the expected response',
"type": "object", type: 'object',
"properties": { properties: {
"format": { format: {
"description": "Expected format of the proof [text, json]", description: 'Expected format of the proof [text, json]',
"type": "string" type: 'string'
}, }
} }
}, },
"target": { target: {
"description": "Details about the target located in the response", description: 'Details about the target located in the response',
"type": "array", type: 'array',
"items": { items: {
"type": "object", type: 'object',
"properties": { properties: {
"format": { format: {
"description": "How is the proof formatted [uri, fingerprint]", description: 'How is the proof formatted [uri, fingerprint]',
"type": "string" type: 'string'
}, },
"encoding": { encoding: {
"description": "How is the proof encoded [plain, html, xml]", description: 'How is the proof encoded [plain, html, xml]',
"type": "string" type: 'string'
}, },
"relation": { relation: {
"description": "How are the response and the target related [contains, equals]", description: 'How are the response and the target related [contains, equals]',
"type": "string" type: 'string'
}, },
"path": { path: {
"description": "Path to the target location if the response is JSON", description: 'Path to the target location if the response is JSON',
"type": "array", type: 'array',
"items": { items: {
"type": "string" type: 'string'
} }
} }
} }
@ -366,11 +365,11 @@ export const serviceProviderSchema = {
} }
} }
}, },
"required": [ required: [
"about", 'about',
"profile", 'profile',
"claim", 'claim',
"proof" 'proof'
], ],
"additionalProperties": false additionalProperties: false
} }

View file

@ -145,7 +145,6 @@ const generateSignatureProfile = async (signature) => {
return fetchSignature(signature) return fetchSignature(signature)
.then(async key => { .then(async key => {
let profile = await doipjs.signatures.parse(key.publicKey) let profile = await doipjs.signatures.parse(key.publicKey)
profile.addVerifier('keyoxide', keyoxideUrl)
profile = processOpenPgpProfile(profile) profile = processOpenPgpProfile(profile)
logger.debug('Generating a signature profile', logger.debug('Generating a signature profile',
@ -255,16 +254,6 @@ const processOpenPgpProfile = async (/** @type {import('doipjs').Profile */ prof
return profile return profile
} }
const computeExtraData = async (key, keyData) => {
// Get the primary user
const primaryUser = await key.publicKey.getPrimaryUser()
// Query libravatar to get the avatar url
return {
avatarURL: await libravatar.get_avatar_url({ email: primaryUser.user.userID.email, size: 128, default: 'mm', https: true })
}
}
export { generateAspeProfile } export { generateAspeProfile }
export { generateWKDProfile } export { generateWKDProfile }
export { generateHKPProfile } export { generateHKPProfile }

View file

@ -29,7 +29,7 @@ more information on this, and how to apply and follow the GNU AGPL, see <https:/
*/ */
import got from 'got' import got from 'got'
import * as doipjs from 'doipjs' import * as doipjs from 'doipjs'
import { readKey, readCleartextMessage, verify, PublicKey } from 'openpgp' import { readKey } from 'openpgp'
import { computeWKDLocalPart } from './utils.js' import { computeWKDLocalPart } from './utils.js'
import { createHash } from 'crypto' import { createHash } from 'crypto'
import Keyv from 'keyv' import Keyv from 'keyv'
@ -176,16 +176,6 @@ const fetchSignature = (signature) => {
(async () => { (async () => {
let profile = null let profile = null
// Check validity of signature
let signatureData
try {
signatureData = await readCleartextMessage({
cleartextMessage: signature
})
} catch (error) {
reject(new Error(`Signature could not be properly read (${error.message})`))
}
// Process the signature // Process the signature
try { try {
profile = await doipjs.signatures.parse(signature) profile = await doipjs.signatures.parse(signature)