Skip to content

Commit

Permalink
modifies id generation logic for status credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
kezike committed Apr 23, 2024
1 parent b01a0c5 commit 5161e0f
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 20 deletions.
35 changes: 22 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ const credential = {
};
const credentialWithStatus = await statusManager.allocateStatus({
credential,
statusPurposes: ['revocation']
statusPurposes: ['revocation', 'suspension']
});
console.log(credentialWithStatus);
/*
Expand All @@ -134,18 +134,27 @@ console.log(credentialWithStatus);
issuer: 'did:key:z6MkhVTX9BF3NGYX6cc7jWpbNnR7cAjH8LUffabZP8Qu4ysC',
validFrom: '2020-03-10T04:24:12.164Z',
credentialSubject: { id: 'did:example:abcdef' },
credentialStatus: {
id: 'https://credentials.example.edu/status/V27UAUYPNR#1',
type: 'BitstringStatusListEntry',
statusPurpose: 'revocation',
statusListIndex: '1',
statusListCredential: 'https://credentials.example.edu/status/V27UAUYPNR'
}
credentialStatus: [
{
id: 'https://credentials.example.edu/status/Uz42qSDSXTcoLH7kZ6ST#1',
type: 'BitstringStatusListEntry',
statusPurpose: 'revocation',
statusListIndex: '1',
statusListCredential: 'https://credentials.example.edu/status/Uz42qSDSXTcoLH7kZ6ST'
},
{
id: 'https://credentials.example.edu/status/9kGimd8POqM88l32F9aT#1',
type: 'BitstringStatusListEntry',
statusPurpose: 'suspension',
statusListIndex: '1',
statusListCredential: 'https://credentials.example.edu/status/9kGimd8POqM88l32F9aT'
}
]
}
*/
```

**Note:** You can also call `allocateRevocationStatus(credential)` to achieve the same effect as `allocateStatus({ credential, statusPurposes: ['revocation'] })` and `allocateSuspensionStatus(credential)` to achieve the same effect as `allocateStatus({ credential, statusPurposes: ['suspension'] })`.
**Note:** You can also call `allocateRevocationStatus(credential)` to achieve the same effect as `allocateStatus({ credential, statusPurposes: ['revocation'] })`, `allocateSuspensionStatus(credential)` to achieve the same effect as `allocateStatus({ credential, statusPurposes: ['suspension'] })`, and `allocateSupportedStatuses(credential)` to achieve the same effect as `allocateStatus({ credential, statusPurposes: ['revocation', 'suspension'] })`.

Additionally, if the caller invokes `allocateStatus` multiple times with the same credential ID against the same instance of a credential status manager, the library will not allocate a new entry. It will just return a credential with the same status info as it did in the previous invocation.

Expand All @@ -167,10 +176,10 @@ console.log(statusCredential);
'@context': [
'https://www.w3.org/ns/credentials/v2'
],
id: 'https://credentials.example.edu/status/V27UAUYPNR',
id: 'https://credentials.example.edu/status/Uz42qSDSXTcoLH7kZ6ST',
type: [ 'VerifiableCredential', 'BitstringStatusListCredential' ],
credentialSubject: {
id: 'https://credentials.example.edu/status/V27UAUYPNR#list',
id: 'https://credentials.example.edu/status/Uz42qSDSXTcoLH7kZ6ST#list',
type: 'BitstringStatusList',
encodedList: 'H4sIAAAAAAAAA-3BMQ0AAAACIGf_0LbwAhoAAAAAAAAAAAAAAIC_AfqBUGnUMAAA',
statusPurpose: 'revocation'
Expand All @@ -195,12 +204,12 @@ console.log(credentialStatus);
/*
{
revocation: {
statusCredentialId: 'V27UAUYPNR',
statusCredentialId: 'Uz42qSDSXTcoLH7kZ6ST',
statusListIndex: 1,
valid: true
},
suspension: {
statusCredentialId: '4R7EA3YPTR',
statusCredentialId: '9kGimd8POqM88l32F9aT',
statusListIndex: 1,
valid: false
}
Expand Down
19 changes: 15 additions & 4 deletions src/credential-status-manager-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
} from './errors.js';
import {
DidMethod,
MAX_ID_LENGTH,
MAX_CREDENTIAL_ID_LENGTH,
getCredentialSubjectObject,
getDateString,
getSigningMaterial,
Expand All @@ -26,6 +26,12 @@ import {
// Number of credentials tracked in a list
const CREDENTIAL_STATUS_LIST_SIZE = 100000;

// Length of status credential ID
const STATUS_CREDENTIAL_ID_LENGTH = 20;

// Character set of status credential ID
const STATUS_CREDENTIAL_ID_CHAR_SET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

// Status credential type
const STATUS_CREDENTIAL_TYPE = 'BitstringStatusListCredential';

Expand Down Expand Up @@ -328,7 +334,12 @@ export abstract class BaseCredentialStatusManager {
* @returns {string} Returns new status credential ID.
*/
generateStatusCredentialId(): string {
return Math.random().toString(36).substring(2, 12).toUpperCase();
let statusCredentialId = '';
const charSetLength = STATUS_CREDENTIAL_ID_CHAR_SET.length;
for (let i = 0; i < STATUS_CREDENTIAL_ID_LENGTH; i++) {
statusCredentialId += STATUS_CREDENTIAL_ID_CHAR_SET.charAt(Math.floor(Math.random() * charSetLength));
}
return statusCredentialId;
}

/**
Expand Down Expand Up @@ -392,8 +403,8 @@ export abstract class BaseCredentialStatusManager {
} else {
if (!isValidCredentialId(credentialCopy.id)) {
throw new BadRequestError({
message: 'The ID must be a URL, UUID, or DID ' +
`that is no more than ${MAX_ID_LENGTH} characters in length.`
message: 'The credential ID must be a URL, UUID, or DID ' +
`that is no more than ${MAX_CREDENTIAL_ID_LENGTH} characters in length.`
});
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ const didKeyDriver = DidKey.driver();
// Document loader
const documentLoader = securityLoader().build();

// Max length for IDs
export const MAX_ID_LENGTH = 64;
// Max length for credential IDs
export const MAX_CREDENTIAL_ID_LENGTH = 64;

// DID method used to sign credentials
export enum DidMethod {
Expand Down Expand Up @@ -199,7 +199,7 @@ function extractId(objectOrString: any): string {
// determines if credential ID is valid
export function isValidCredentialId(credentialId: string): boolean {
const isValidFormat = URL.canParse(credentialId) || uuid.validate(credentialId);
const isValidLength = credentialId.length <= MAX_ID_LENGTH;
const isValidLength = credentialId.length <= MAX_CREDENTIAL_ID_LENGTH;
return isValidFormat && isValidLength;
}

Expand Down

0 comments on commit 5161e0f

Please sign in to comment.