Skip to content

Commit

Permalink
Merge pull request #1641 from blockchain-certificates/feat/verifiable…
Browse files Browse the repository at this point in the history
…-presentations

Feat/verifiable presentations
  • Loading branch information
lemoustachiste authored Nov 27, 2024
2 parents 05df1b2 + f7f84f0 commit ad2c2ec
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 26 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"node": ">=18.0.0"
},
"dependencies": {
"@blockcerts/cert-verifier-js": "^6.22.0",
"@blockcerts/cert-verifier-js": "^6.22.1",
"@blockcerts/cert-verifier-js-v1-legacy": "^4.0.1",
"@polymer/lit-element": "0.5.1",
"@polymer/polymer": "3.5.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ const ownProps: FinalVerificationStepProps = {
isVisible: Boolean as any,
hideLink: Boolean as any,
standalone: Boolean as any,
isOverlay: Boolean as any
isOverlay: Boolean as any,
status: String as any,
finalStep: Object as any
};

const FinalVerificationStepContainer = connector(FinalVerificationStep, { mapStateToProps, ownProps });
Expand Down
16 changes: 12 additions & 4 deletions src/components/organisms/FullCertificate/FullCertificate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import CSS from './_components.full-certificate-css';
import '../../atoms/CertificateDetails';
import '../../atoms/VerifyButton';
import '../../atoms/FinalVerificationStep';
import '../VerifiablePresentation';
import getText from '../../../i18n/getText';
import urlToLink from '../../../helpers/urlToLink';
import domain from '../../../domain';
import type { IFullScreenCertificateAPI } from '../FullScreenCertificate/FullScreenCertificate';

function renderDisplayHTML (displayHTML: string, clickableUrls: boolean): TemplateResult {
function renderDisplayHTML (displayHTML: string, clickableUrls: boolean, isVerifiablePresentation: boolean): TemplateResult {
const buvCertificateClasses: string[] = [
'buv-c-full-certificate',
'qa-fullscreen-certificate'
Expand All @@ -20,13 +21,17 @@ function renderDisplayHTML (displayHTML: string, clickableUrls: boolean): Templa
}

const htmlToDisplay = clickableUrls ? urlToLink(displayHTML) : displayHTML;
if (isVerifiablePresentation) {
return html`<buv-verifiable-presentation></buv-verifiable-presentation>`;
}
return html`<section class$=${buvCertificateClasses.join(' ')}>${unsafeHTML(htmlToDisplay)}</section>`;
}

export interface IFullCertificateAPI {
clickableUrls?: boolean;
hasCertificateDefinition?: boolean;
displayHTML?: string;
isVerifiablePresentation?: boolean;
}

export class FullCertificateComponent extends LitElement {
Expand All @@ -35,7 +40,8 @@ export class FullCertificateComponent extends LitElement {
return {
clickableUrls: Boolean as any,
hasCertificateDefinition: Boolean as any,
displayHTML: String as any
displayHTML: String as any,
isVerifiablePresentation: Boolean as any
};
}

Expand All @@ -52,7 +58,8 @@ export class FullCertificateComponent extends LitElement {
_render ({
clickableUrls,
hasCertificateDefinition,
displayHTML
displayHTML,
isVerifiablePresentation
}: IFullCertificateAPI): TemplateResult {
if (!hasCertificateDefinition) {
// lit-element won't enter the rendering path if the content is null
Expand All @@ -62,7 +69,7 @@ export class FullCertificateComponent extends LitElement {

return html`
${CSS}
${renderDisplayHTML(displayHTML, clickableUrls)}
${renderDisplayHTML(displayHTML, clickableUrls, isVerifiablePresentation)}
<div class='buv-c-full-certificate__details'>
<buv-final-verification-step class='buv-c-fullscreen-certificate__verification-status' isVisible hideLink standalone>
<buv-verify-button type='link'>${getText('text.verifyAgain')}</buv-verify-button>
Expand All @@ -80,6 +87,7 @@ function FullCertificateWrapper (props: IFullCertificateAPI): TemplateResult {
clickableUrls = '${props.clickableUrls}'
hasCertificateDefinition = '${props.hasCertificateDefinition}'
displayHTML = '${props.displayHTML}'
isVerifiablePresentation = '${props.isVerifiablePresentation}'
></buv-full-certificate-raw>`;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ import type { IFullCertificateAPI } from './FullCertificate';
import { FullCertificate } from './FullCertificate';
import {
getCertificateDefinition,
getDisplayAsHTML
getDisplayAsHTML, getIsVerifiablePresentation
} from '../../../selectors/certificate';
import { getClickableUrls } from '../../../selectors/api';
import type { BlockcertsVerifierState } from '../../../store/getInitialState';

export const mapStateToProps = (state: BlockcertsVerifierState): Partial<IFullCertificateAPI> => ({
hasCertificateDefinition: !!getCertificateDefinition(state),
displayHTML: getDisplayAsHTML(state),
clickableUrls: getClickableUrls(state)
clickableUrls: getClickableUrls(state),
isVerifiablePresentation: getIsVerifiablePresentation(state)
});

const FullCertificateContainer = connector<any, Partial<IFullCertificateAPI>, any>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import type { TemplateResult } from 'lit-html';
import '../../atoms/FinalVerificationStep';

export interface IVerifiablePresentationApi {
verifiableCredentials: any[];
// this is a hack to force rerenders as the verification of individual credentials occurs
verifiableCredentials: string;
}

class VerifiablePresentation extends LitElement {
Expand All @@ -16,7 +17,8 @@ class VerifiablePresentation extends LitElement {
static get properties (): IVerifiablePresentationApi {
// if the interface is defined properly with typescript, then the boolean values do not get updated.
return {
verifiableCredentials: Array as any
// this is a hack to force rerenders as the verification of individual credentials occurs
verifiableCredentials: String as any
};
}

Expand Down Expand Up @@ -65,11 +67,13 @@ class VerifiablePresentation extends LitElement {
});
}

_render ({ verifiableCredentials }): TemplateResult {
_render ({ verifiableCredentials }: IVerifiablePresentationApi): TemplateResult {
// this is a hack to force rerenders as the verification of individual credentials occurs
const VCList: any[] = JSON.parse(verifiableCredentials);
return html`
${CSS}
<ul>
${verifiableCredentials.map((credential, i) => {
${VCList.map((credential, i) => {
const linkClasslist = [
'js-verifiable-presentation-navigation',
'buv-c-verifiable-presentation-navigation__link',
Expand All @@ -89,12 +93,16 @@ class VerifiablePresentation extends LitElement {
</ul>
<div class="slider">
<ul class="buv-c-verifiable-presentation js-scroll-snap-item">
${verifiableCredentials.map((credential) => html`
${VCList.map((credential) => html`
<li id$="${credential.id}" class="buv-c-verifiable-presentation__credential">
${unsafeHTML(getV3DisplayHtml(credential))}
<buv-final-verification-step
finalStep="${getVerificationStatusForCredential(credential)?.message}"
status="${getVerificationStatusForCredential(credential)?.status}"
finalStep="${
typeof getVerificationStatusForCredential(credential)?.message === 'string'
? { label: getVerificationStatusForCredential(credential)?.message }
: getVerificationStatusForCredential(credential)?.message
}"
status$="${getVerificationStatusForCredential(credential)?.status}"
isVisible
standalone
isOverlay
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { getVerifiableCredentials } from '../../../selectors/certificate';
import { VerifiablePresentation } from './VerifiablePresentation';

export const mapStateToProps = (state: BlockcertsVerifierState): Partial<IVerifiablePresentationApi> => ({
verifiableCredentials: getVerifiableCredentials(state)
// this is a hack to force rerenders as the verification of individual credentials occurs
verifiableCredentials: JSON.stringify(getVerifiableCredentials(state))
});

const VerifiablePresentationContainer = connector(VerifiablePresentation, { mapStateToProps });
Expand Down
6 changes: 2 additions & 4 deletions src/selectors/certificate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,8 @@ export function getDisplayAsHTML (state: BlockcertsVerifierState): string {

// V3
if (getIsVerifiablePresentation(state)) {
// TODO: this is useless as VPs are handled by their own component
return getVerifiableCredentials(state).map(credential => {
return `<li>${getV3DisplayHtml(credential)}</li>`;
}).join('\n');
// return basic html to trigger rendering
return '<div></div>';
} else {
displayHtml = getV3DisplayHtml(certificateDefinition);
if (displayHtml) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ describe('certificate selectors test suite', function () {
describe('getDisplayAsHTML selector', function () {
it('should return the display HTML as coded into the document', function () {
const state = store.getState();
expect(getDisplayAsHTML(state)).toBe('<li><div style="background-color:transparent;padding:6px;display:inline-flex;align-items:center;flex-direction:column;">Yo</div></li>\n' +
'<li><div style="background-color:transparent;padding:6px;display:inline-flex;align-items:center;flex-direction:column;">Yo</div></li>');
expect(getDisplayAsHTML(state)).toBe('<div></div>');
});
});
});
Expand Down

0 comments on commit ad2c2ec

Please sign in to comment.