Skip to content

Commit

Permalink
Merge pull request #745 from walt-id/wallet&portalfixes
Browse files Browse the repository at this point in the history
fix: Wallet & Portal Bugs
  • Loading branch information
mikeplotean authored Sep 13, 2024
2 parents 20e4c10 + 2852ebd commit 27e4865
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 98 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import RowCredential from '@/components/walt/credential/RowCredential';
import Dropdown from '@/components/walt/forms/Dropdown';
import {AuthenticationMethods, VpProfiles} from '@/types/credentials'
import { AuthenticationMethods, VpProfiles } from '@/types/credentials'
import Checkbox from '@/components/walt/forms/Checkbox';
import InputField from '@/components/walt/forms/Input';
import Button from '@/components/walt/button/Button';
Expand Down Expand Up @@ -115,11 +115,11 @@ export default function IssueSection() {
<span> Authentication Method</span>
</div>
</div>
<Dropdown
values={AuthenticationMethods}
selected={selectedAuthenticationMethod}
setSelected={setSelectedAuthenticationMethod}
/>
<Dropdown
values={AuthenticationMethods}
selected={selectedAuthenticationMethod}
setSelected={setSelectedAuthenticationMethod}
/>
</div>
<div className="mt-3 flex flex-col sm:flex-row justify-between">
<div className="">
Expand Down Expand Up @@ -155,16 +155,16 @@ export default function IssueSection() {
</div>

<div className="mt-1 flex flex-col sm:flex-row justify-between">
<div className="">
<div className="">
<Checkbox value={requireVpProfile} onChange={setRequireVpProfile}>
VP Token Requested Profile
</Checkbox>
</div>
<Dropdown
values={VpProfiles}
selected={selectedVpProfile}
setSelected={setSelectedVpProfile}
/>
<Dropdown
values={VpProfiles}
selected={selectedVpProfile}
setSelected={setSelectedVpProfile}
/>
</div>

<hr className="my-5" />
Expand All @@ -173,7 +173,11 @@ export default function IssueSection() {
Cancel
</Button>
<Button
disabled={!(credentialsToIssue.length > 0 && (credentialsToIssue.length < 2 || credentialsToIssue.filter((cred) => cred.selectedFormat === "SD-JWT + VCDM").length === 0))}
disabled={!(credentialsToIssue.length > 0 && (
credentialsToIssue.length < 2 ||
credentialsToIssue.filter((cred) => cred.selectedFormat === "SD-JWT + W3C VC" || cred.selectedFormat === "SD-JWT + IETF SD-JWT VC").length === credentialsToIssue.length ||
credentialsToIssue.filter((cred) => !cred.selectedFormat || cred.selectedFormat === "JWT + W3C VC").length === credentialsToIssue.length
))}
onClick={handleIssue}>Issue</Button>
</div>
<div className="flex flex-col items-center mt-12">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function Checkbox({
name="comments"
type="checkbox"
checked={value}
onClick={() => {
onChange={() => {
onChange(!value);
}}
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
Expand Down
124 changes: 47 additions & 77 deletions waltid-applications/waltid-web-portal/utils/getOfferUrl.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';
import {AvailableCredential, CredentialFormats, DIDMethods, DIDMethodsConfig} from '@/types/credentials';
import { AvailableCredential, CredentialFormats, DIDMethods, DIDMethodsConfig } from '@/types/credentials';

const getOfferUrl = async (credentials: Array<AvailableCredential>, NEXT_PUBLIC_VC_REPO: string, NEXT_PUBLIC_ISSUER: string, authenticationMethod?: string, vpRequestValue?: string, vpProfile?: string) => {
const getOfferUrl = async (credentials: Array<AvailableCredential>, NEXT_PUBLIC_VC_REPO: string, NEXT_PUBLIC_ISSUER: string, authenticationMethod?: string, vpRequestValue?: string, vpProfile?: string) => {
const data = await fetch(`${NEXT_PUBLIC_ISSUER}/.well-known/openid-credential-issuer`).then(data => {
return data.json();
});
const credential_configurations_supported = data.credential_configurations_supported;

const payload = await Promise.all(credentials.map(async (c) => {
c = {...c, selectedFormat: c.selectedFormat ?? CredentialFormats[0], selectedDID: c.selectedDID ?? DIDMethods[0]};
c = { ...c, selectedFormat: c.selectedFormat ?? CredentialFormats[0], selectedDID: c.selectedDID ?? DIDMethods[0] };

const offer = { ...c.offer, id: uuidv4() };
const mapping = await (await fetch(`${NEXT_PUBLIC_VC_REPO}/api/mapping/${c.id}`).then(data => {
return data.json();
}).catch(err => {
return null;
}));

let payload: {
'issuerDid': string,
'issuerKey': { "type": string, "jwk": object },
Expand All @@ -35,27 +29,13 @@ const getOfferUrl = async (credentials: Array<AvailableCredential>, NEXT_PUBLIC_
credentialData: offer
}

if (c.selectedFormat === "SD-JWT + W3C VC") {
payload.selectiveDisclosure = {
"fields": {
"credentialSubject": {
sd: false,
children: {
fields: {}
}
}
}
}
for (const key in offer.credentialSubject) {
if (typeof offer.credentialSubject[key] === 'string') {
payload.selectiveDisclosure.fields.credentialSubject.children.fields[key] = {
sd: true
}
}
}
}

if (c.selectedFormat === "SD-JWT + IETF SD-JWT VC"){
if (c.selectedFormat === "SD-JWT + IETF SD-JWT VC") {
payload.mapping = {
id: "<uuid>",
iat: "<timestamp-seconds>",
nbf: "<timestamp-seconds>",
exp: "<timestamp-in-seconds:365d>"
};

// Hack - remove the following fields as they used for w3c only
delete payload.credentialData["@context"];
Expand All @@ -66,80 +46,70 @@ const getOfferUrl = async (credentials: Array<AvailableCredential>, NEXT_PUBLIC_
delete payload.credentialData["issued"];
delete payload.credentialData["issuer"];

// Hack - replace the "mapping" object with the new one
// delete payload.mapping;

payload.mapping = {
id: "<uuid>",
iat: "<timestamp-seconds>",
nbf: "<timestamp-seconds>",
exp: "<timestamp-in-seconds:365d>"
};

payload.credentialConfigurationId = Object.keys(credential_configurations_supported).find(key => key === c.id + "_vc+sd-jwt") as string;

interface SelectiveDisclosureField {
sd: boolean;
children: {
fields: Record<string, any>;
};
}

const selectiveDisclosure: {
fields: Record<string, SelectiveDisclosureField>;
} = {
fields: {}
};

payload.selectiveDisclosure = { "fields": {} }
for (const key in offer.credentialSubject) {
if (typeof offer.credentialSubject[key] === 'string') {
// Add a field entry for each property in credentialSubject
selectiveDisclosure.fields[key] = {
sd: true, // Default selective disclosure state
children: {
fields: {} // Placeholder for potential future nested fields
payload.selectiveDisclosure.fields[key] = {
sd: true
}
}
}
}
else {
payload.mapping = await (await fetch(`${NEXT_PUBLIC_VC_REPO}/api/mapping/${c.id}`).then(data => {
return data.json();
}).catch(err => {
return null;
}));

if (c.selectedFormat === "SD-JWT + W3C VC") {
payload.selectiveDisclosure = {
"fields": {
"credentialSubject": {
sd: false,
children: {
fields: {}
}
}
}
}
for (const key in offer.credentialSubject) {
if (typeof offer.credentialSubject[key] === 'string') {
payload.selectiveDisclosure.fields.credentialSubject.children.fields[key] = {
sd: true
}
};
}
}
}

payload.selectiveDisclosure = selectiveDisclosure

}

if (authenticationMethod) {
payload.authenticationMethod = authenticationMethod;
}

if (vpRequestValue) {
payload.vpRequestValue = vpRequestValue;
}

if (vpProfile) {
payload.vpProfile = vpProfile;
}

// If true, return the payload as is
if (credentials[0]?.selectedFormat === "SD-JWT + IETF SD-JWT VC") {

if (c.selectedFormat === "SD-JWT + IETF SD-JWT VC") {
const { credentialSubject, ...restOfCredentialData } = payload.credentialData; // Destructure credentialSubject and the rest

const updatedPayload = {
return {
...payload, // Keep the rest of the payload unchanged
credentialData: {
...restOfCredentialData, // Spread other fields from credentialData (e.g., id, issuer)
...credentialSubject // Spread fields from credentialSubject to the top level of credentialData
}
};

return updatedPayload
}

// Otherwise, return the payload with mapping if mapping exists, or just payload
return mapping ? { ...payload, mapping } : payload;
else {
return payload;
}
}));


const issueUrl = NEXT_PUBLIC_ISSUER + `/openid4vc/${credentials.length === 1 && (credentials[0].selectedFormat === "SD-JWT + W3C VC" || credentials[0].selectedFormat === "SD-JWT + IETF SD-JWT VC") ? "sdjwt" : "jwt"}/${(payload.length > 1 ? 'issueBatch' : 'issue')}`;
const issueUrl = NEXT_PUBLIC_ISSUER + `/openid4vc/${credentials[0].selectedFormat === "SD-JWT + W3C VC" || credentials[0].selectedFormat === "SD-JWT + IETF SD-JWT VC" ? "sdjwt" : "jwt"}/${(payload.length > 1 ? 'issueBatch' : 'issue')}`;
return axios.post(issueUrl, payload.length > 1 ? payload : payload[0]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
d="M15 19l-7-7 7-7" />
</svg>
</button>
<VerifiableCredentialCard :credential="{
<VerifiableCredentialCard :key="index" :credential="{
parsedDocument: {
type: [credentialTypes[index]],
issuer: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export default defineNuxtConfig({
projectId: process.env.ProjectId,
issuerCallbackUrl: "http://localhost:7100",
credentialsRepositoryUrl: "http://localhost:3000",
devWalletUrl: "https://wallet-dev.walt.id",
demoWalletUrl: "https://wallet-dev.walt.id",
}
},

Expand Down
7 changes: 4 additions & 3 deletions waltid-services/waltid-wallet-api/k8s/deployment-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ spec:
- name: NUXT_PUBLIC_DEMO_WALLET_URL
value: "https://wallet.walt-test.cloud"
ports:
- containerPort: 7101
- containerPort: 7104
name: http-api
---
kind: Deployment
Expand All @@ -190,7 +190,7 @@ spec:
env:
- name: NUXT_PUBLIC_ISSUER_CALLBACK_URL
value: "https://wallet.walt-test.cloud"
- name: NUXT_PUBLIC_DEMO_WALLET_URL
- name: NUXT_PUBLIC_DEV_WALLET_URL
value: "https://wallet-dev.walt-test.cloud"
- name: NUXT_PUBLIC_CREDENTIALS_REPOSITORY_URL
value: "https://vc-repo.walt-test.cloud"
Expand Down Expand Up @@ -239,9 +239,10 @@ spec:
tls:
- hosts:
- wallet.walt-test.cloud
secretName: test-wallet-demo-tls-secret
- hosts:
- wallet-dev.walt-test.cloud
secretName: wallet-tls-secret
secretName: test-wallet-dev-tls-secret
rules:
- host: wallet-dev.walt-test.cloud
http:
Expand Down
4 changes: 2 additions & 2 deletions waltid-services/waltid-wallet-api/k8s/deployment-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ spec:
- name: NUXT_PUBLIC_DEMO_WALLET_URL
value: "https://wallet.walt.id"
ports:
- containerPort: 7101
- containerPort: 7104
name: http-api
---
kind: Service
Expand Down Expand Up @@ -200,7 +200,7 @@ spec:
env:
- name: NUXT_PUBLIC_ISSUER_CALLBACK_URL
value: "https://wallet.walt.id"
- name: NUXT_PUBLIC_DEMO_WALLET_URL
- name: NUXT_PUBLIC_DEV_WALLET_URL
value: "https://wallet-dev.walt.id"
- name: NUXT_PUBLIC_CREDENTIALS_REPOSITORY_URL
value: "https://credentials.walt.id"
Expand Down

0 comments on commit 27e4865

Please sign in to comment.