diff --git a/src/api/v3/keyoxide_profile.js b/src/api/v3/keyoxide_profile.js index b1ba960..ed8ebd5 100644 --- a/src/api/v3/keyoxide_profile.js +++ b/src/api/v3/keyoxide_profile.js @@ -37,7 +37,7 @@ import { claimSchema, personaSchema, profileSchema, serviceProviderSchema } from dotenv.config() const router = express.Router() -const ajv = new Ajv({ +const ajv = new Ajv({ schemas: [profileSchema, personaSchema, claimSchema, serviceProviderSchema] }) @@ -157,7 +157,7 @@ router.get('/verify', return } - let profile = Claim.fromJson(req.query.data) + const profile = Claim.fromJson(req.query.data) // Do verification let data = await doVerification(profile) diff --git a/src/schemas.js b/src/schemas.js index 9ac16ae..9c4a77f 100644 --- a/src/schemas.js +++ b/src/schemas.js @@ -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 . */ export const profileSchema = { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://spec.keyoxide.org/2/profile.schema.json", - "title": "Profile", - "description": "Keyoxide profile with personas", - "type": "object", - "properties": { - "profileVersion": { - "description": "The version of the profile", - "type": "integer" + $schema: 'https://json-schema.org/draft/2020-12/schema', + $id: 'https://spec.keyoxide.org/2/profile.schema.json', + title: 'Profile', + description: 'Keyoxide profile with personas', + type: 'object', + properties: { + profileVersion: { + description: 'The version of the profile', + type: 'integer' }, - "profileType": { - "description": "The type of the profile [openpgp, asp]", - "type": "string" + profileType: { + description: 'The type of the profile [openpgp, asp]', + type: 'string' }, - "identifier": { - "description": "Identifier of the profile (email, fingerprint, URI)", - "type": "string" + identifier: { + description: 'Identifier of the profile (email, fingerprint, URI)', + type: 'string' }, - "personas": { - "description": "The personas inside the profile", - "type": "array", - "items": { - "$ref": "https://spec.keyoxide.org/2/persona.schema.json" + personas: { + description: 'The personas inside the profile', + type: 'array', + items: { + $ref: 'https://spec.keyoxide.org/2/persona.schema.json' }, - "minItems": 1, - "uniqueItems": true + minItems: 1, + uniqueItems: true }, - "primaryPersonaIndex": { - "description": "The index of the primary persona", - "type": "integer" + primaryPersonaIndex: { + description: 'The index of the primary persona', + type: 'integer' }, - "publicKey": { - "description": "The cryptographic key associated with the profile", - "type": "object", - "properties": { - "keyType": { - "description": "The type of cryptographic key [eddsa, es256, openpgp, none]", - "type": "string" + publicKey: { + description: 'The cryptographic key associated with the profile', + type: 'object', + properties: { + keyType: { + description: 'The type of cryptographic key [eddsa, es256, openpgp, none]', + type: 'string' }, - "encoding": { - "description": "The encoding of the cryptographic key [pem, jwk, armored_pgp, none]", - "type": "string" + encoding: { + description: 'The encoding of the cryptographic key [pem, jwk, armored_pgp, none]', + type: 'string' }, - "encodedKey": { - "description": "The encoded cryptographic key (PEM, stringified JWK, ...)", - "type": ["string", "null"] + encodedKey: { + description: 'The encoded cryptographic key (PEM, stringified JWK, ...)', + type: ['string', 'null'] }, - "fetch": { - "description": "Details on how to fetch the public key", - "type": "object", - "properties": { - "method": { - "description": "The method to fetch the key [aspe, hkp, wkd, http, none]", - "type": "string" + fetch: { + description: 'Details on how to fetch the public key', + type: 'object', + properties: { + method: { + description: 'The method to fetch the key [aspe, hkp, wkd, http, none]', + type: 'string' }, - "query": { - "description": "The query to fetch the key", - "type": ["string", "null"] + query: { + description: 'The query to fetch the key', + type: ['string', 'null'] }, - "resolvedUrl": { - "description": "The URL the method eventually resolved to", - "type": ["string", "null"] + resolvedUrl: { + description: 'The URL the method eventually resolved to', + type: ['string', 'null'] } } } }, - "required": [ - "keyType", - "fetch" + required: [ + 'keyType', + 'fetch' ] }, - "verifiers": { - "description": "A list of links to verifiers", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "description": "Name of the verifier site", - "type": "string" + verifiers: { + description: 'A list of links to verifiers', + type: 'array', + items: { + type: 'object', + properties: { + name: { + description: 'Name of the verifier site', + type: 'string' }, - "url": { - "description": "URL to the profile page on the verifier site", - "type": "string" + url: { + description: 'URL to the profile page on the verifier site', + type: 'string' } } }, - "uniqueItems": true + uniqueItems: true } }, - "required": [ - "profileVersion", - "profileType", - "identifier", - "personas", - "primaryPersonaIndex", - "publicKey", - "verifiers" + required: [ + 'profileVersion', + 'profileType', + 'identifier', + 'personas', + 'primaryPersonaIndex', + 'publicKey', + 'verifiers' ], - "additionalProperties": false + additionalProperties: false } - export const personaSchema = { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://spec.keyoxide.org/2/persona.schema.json", - "title": "Profile", - "description": "Keyoxide persona with identity claims", - "type": "object", - "properties": { - "identifier": { - "description": "Identifier of the persona", - "type": ["string", "null"] + $schema: 'https://json-schema.org/draft/2020-12/schema', + $id: 'https://spec.keyoxide.org/2/persona.schema.json', + title: 'Profile', + description: 'Keyoxide persona with identity claims', + type: 'object', + properties: { + identifier: { + description: 'Identifier of the persona', + type: ['string', 'null'] }, - "name": { - "description": "Name of the persona", - "type": "string" + name: { + description: 'Name of the persona', + type: 'string' }, - "email": { - "description": "Email address of the persona", - "type": ["string", "null"] + email: { + description: 'Email address of the persona', + type: ['string', 'null'] }, - "description": { - "description": "Description of the persona", - "type": ["string", "null"] + description: { + description: 'Description of the persona', + type: ['string', 'null'] }, - "avatarUrl": { - "description": "URL to an avatar image", - "type": ["string", "null"] + avatarUrl: { + description: 'URL to an avatar image', + type: ['string', 'null'] }, - "isRevoked": { - "type": "boolean" + isRevoked: { + type: 'boolean' }, - "claims": { - "description": "A list of identity claims", - "type": "array", - "items": { - "$ref": "https://spec.keyoxide.org/2/claim.schema.json" + claims: { + description: 'A list of identity claims', + type: 'array', + items: { + $ref: 'https://spec.keyoxide.org/2/claim.schema.json' }, - "uniqueItems": true + uniqueItems: true } }, - "required": [ - "name", - "claims" + required: [ + 'name', + 'claims' ], - "additionalProperties": false + additionalProperties: false } export const claimSchema = { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://spec.keyoxide.org/2/claim.schema.json", - "title": "Identity claim", - "description": "Verifiable online identity claim", - "type": "object", - "properties": { - "claimVersion": { - "description": "The version of the claim", - "type": "integer" + $schema: 'https://json-schema.org/draft/2020-12/schema', + $id: 'https://spec.keyoxide.org/2/claim.schema.json', + title: 'Identity claim', + description: 'Verifiable online identity claim', + type: 'object', + properties: { + claimVersion: { + description: 'The version of the claim', + type: 'integer' }, - "uri": { - "description": "The claim URI", - "type": "string" + uri: { + description: 'The claim URI', + type: 'string' }, - "proofs": { - "description": "The proofs that would verify the claim", - "type": "array", - "items": { - "type": "string" + proofs: { + description: 'The proofs that would verify the claim', + type: 'array', + items: { + type: 'string' }, - "minItems": 1, - "uniqueItems": true + minItems: 1, + uniqueItems: true }, - "matches": { - "description": "Service providers matched to the claim", - "type": "array", - "items": { - "$ref": "https://spec.keyoxide.org/2/serviceprovider.schema.json" + matches: { + description: 'Service providers matched to the claim', + type: 'array', + items: { + $ref: 'https://spec.keyoxide.org/2/serviceprovider.schema.json' }, - "uniqueItems": true + uniqueItems: true }, - "status": { - "type": "integer", - "description": "Claim status code" + status: { + type: 'integer', + description: 'Claim status code' }, - "display": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Account name to display in the user interface" + display: { + type: 'object', + properties: { + name: { + type: 'string', + description: 'Account name to display in the user interface' }, - "url": { - "type": ["string", "null"], - "description": "URL to link to in the user interface" + url: { + type: ['string', 'null'], + description: 'URL to link to in the user interface' }, - "serviceProviderName": { - "type": ["string", "null"], - "description": "Name of the service provider to display in the user interface" + serviceProviderName: { + type: ['string', 'null'], + description: 'Name of the service provider to display in the user interface' } } } }, - "required": [ - "claimVersion", - "uri", - "proofs", - "status", - "display" + required: [ + 'claimVersion', + 'uri', + 'proofs', + 'status', + 'display' ], - "additionalProperties": false + additionalProperties: false } export const serviceProviderSchema = { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://spec.keyoxide.org/2/serviceprovider.schema.json", - "title": "Service provider", - "description": "A service provider that can be matched to identity claims", - "type": "object", - "properties": { - "about": { - "description": "Details about the service provider", - "type": "object", - "properties": { - "name": { - "description": "Full name of the service provider", - "type": "string" + $schema: 'https://json-schema.org/draft/2020-12/schema', + $id: 'https://spec.keyoxide.org/2/serviceprovider.schema.json', + title: 'Service provider', + description: 'A service provider that can be matched to identity claims', + type: 'object', + properties: { + about: { + description: 'Details about the service provider', + type: 'object', + properties: { + name: { + description: 'Full name of the service provider', + type: 'string' }, - "id": { - "description": "Identifier of the service provider (no whitespace or symbols, lowercase)", - "type": "string" + id: { + description: 'Identifier of the service provider (no whitespace or symbols, lowercase)', + type: 'string' }, - "homepage": { - "description": "URL to the homepage of the service provider", - "type": ["string", "null"] + homepage: { + description: 'URL to the homepage of the service provider', + type: ['string', 'null'] } } }, - "profile": { - "description": "What the profile would look like if the match is correct", - "type": "object", - "properties": { - "display": { - "description": "Profile name to be displayed", - "type": "string" + profile: { + description: 'What the profile would look like if the match is correct', + type: 'object', + properties: { + display: { + description: 'Profile name to be displayed', + type: 'string' }, - "uri": { - "description": "URI or URL for public access to the profile", - "type": "string" + uri: { + description: 'URI or URL for public access to the profile', + type: 'string' }, - "qr": { - "description": "URI or URL associated with the profile usually served as a QR code", - "type": ["string", "null"] + qr: { + description: 'URI or URL associated with the profile usually served as a QR code', + type: ['string', 'null'] } } }, - "claim": { - "description": "Details from the claim matching process", - "type": "object", - "properties": { - "uriRegularExpression": { - "description": "Regular expression used to parse the URI", - "type": "string" + claim: { + description: 'Details from the claim matching process', + type: 'object', + properties: { + uriRegularExpression: { + description: 'Regular expression used to parse the URI', + type: 'string' }, - "uriIsAmbiguous": { - "description": "Whether this match automatically excludes other matches", - "type": "boolean" + uriIsAmbiguous: { + description: 'Whether this match automatically excludes other matches', + type: 'boolean' } } }, - "proof": { - "description": "Information for the proof verification process", - "type": "object", - "properties": { - "request": { - "description": "Details to request the potential proof", - "type": "object", - "properties": { - "uri": { - "description": "Location of the proof", - "type": ["string", "null"] + proof: { + description: 'Information for the proof verification process', + type: 'object', + properties: { + request: { + description: 'Details to request the potential proof', + type: 'object', + properties: { + uri: { + description: 'Location of the proof', + type: ['string', 'null'] }, - "accessRestriction": { - "description": "Type of access restriction [none, nocors, granted, server]", - "type": "string" + accessRestriction: { + description: 'Type of access restriction [none, nocors, granted, server]', + type: 'string' }, - "fetcher": { - "description": "Name of the fetcher to use", - "type": "string" + fetcher: { + description: 'Name of the fetcher to use', + type: 'string' }, - "data": { - "description": "Data needed by the fetcher or proxy to request the proof", - "type": "object", - "additionalProperties": true + data: { + description: 'Data needed by the fetcher or proxy to request the proof', + type: 'object', + additionalProperties: true } } }, - "response": { - "description": "Details about the expected response", - "type": "object", - "properties": { - "format": { - "description": "Expected format of the proof [text, json]", - "type": "string" - }, + response: { + description: 'Details about the expected response', + type: 'object', + properties: { + format: { + description: 'Expected format of the proof [text, json]', + type: 'string' + } } }, - "target": { - "description": "Details about the target located in the response", - "type": "array", - "items": { - "type": "object", - "properties": { - "format": { - "description": "How is the proof formatted [uri, fingerprint]", - "type": "string" + target: { + description: 'Details about the target located in the response', + type: 'array', + items: { + type: 'object', + properties: { + format: { + description: 'How is the proof formatted [uri, fingerprint]', + type: 'string' }, - "encoding": { - "description": "How is the proof encoded [plain, html, xml]", - "type": "string" + encoding: { + description: 'How is the proof encoded [plain, html, xml]', + type: 'string' }, - "relation": { - "description": "How are the response and the target related [contains, equals]", - "type": "string" + relation: { + description: 'How are the response and the target related [contains, equals]', + type: 'string' }, - "path": { - "description": "Path to the target location if the response is JSON", - "type": "array", - "items": { - "type": "string" + path: { + description: 'Path to the target location if the response is JSON', + type: 'array', + items: { + type: 'string' } } } @@ -366,11 +365,11 @@ export const serviceProviderSchema = { } } }, - "required": [ - "about", - "profile", - "claim", - "proof" + required: [ + 'about', + 'profile', + 'claim', + 'proof' ], - "additionalProperties": false + additionalProperties: false } diff --git a/src/server/index.js b/src/server/index.js index 176425d..d0b4a4f 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -145,7 +145,6 @@ const generateSignatureProfile = async (signature) => { return fetchSignature(signature) .then(async key => { let profile = await doipjs.signatures.parse(key.publicKey) - profile.addVerifier('keyoxide', keyoxideUrl) profile = processOpenPgpProfile(profile) logger.debug('Generating a signature profile', @@ -255,16 +254,6 @@ const processOpenPgpProfile = async (/** @type {import('doipjs').Profile */ prof 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 { generateWKDProfile } export { generateHKPProfile } diff --git a/src/server/openpgpProfiles.js b/src/server/openpgpProfiles.js index 8bec8fd..2192bbe 100644 --- a/src/server/openpgpProfiles.js +++ b/src/server/openpgpProfiles.js @@ -29,7 +29,7 @@ more information on this, and how to apply and follow the GNU AGPL, see { (async () => { 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 try { profile = await doipjs.signatures.parse(signature)