Skip to content

Commit 05f431a

Browse files
author
Bnonni
committed
pushing latest changes for expiration
1 parent 968f052 commit 05f431a

File tree

4 files changed

+55
-28
lines changed

4 files changed

+55
-28
lines changed

json-schemas/interface-methods/protocol-rule-set.json

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,21 @@
112112
"additionalProperties": false,
113113
"properties": {
114114
"duration": {
115-
"type": "number",
116-
"minimum": 1,
117-
"$comment": "Amount of milliseconds to add to dateCreated to determine expiration date"
118-
},
119-
"timespan": {
120-
"type": "string",
121-
"minimum": "1s",
122-
"$comment": "Amount of time concatenated to time unit to convert and add to dateCreated to determine expiration date. e.g. 30s, 45m, 10h, 2D, 3W, 6M, 2Y"
115+
"oneOf": [
116+
{
117+
"type": "string",
118+
"$comment": "A number and a time unit formatted as <amount><unit> representing an amount of time to wait before expiration. Smallest possible <amount><unit> value is 1s. s = seconds, m = minutes, h = hours, d = days, y = years. e.g. 30s, 45m, 10h, 2d, 2y"
119+
},
120+
{
121+
"type": "number",
122+
"minimum": 1,
123+
"$comment": "Amount of milliseconds to wait before expiration."
124+
}
125+
]
123126
},
124127
"datetime": {
125128
"type": "string",
126-
"$comment": "Explicit expiration date and time in ISO8601 format YYYY-MM-DDThh:mm:ssZ."
129+
"$comment": "Explicit expiration datetime string in ISO-8601 UTC format (YYYY-MM-DDThh:mm:ssZ). e.g. 1970-01-01T00:00:00Z"
127130
}
128131
}
129132
}

src/core/dwn-error.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export enum DwnErrorCode {
5555
PrivateKeySignerUnsupportedCurve = 'PrivateKeySignerUnsupportedCurve',
5656
ProtocolAuthorizationActionNotAllowed = 'ProtocolAuthorizationActionNotAllowed',
5757
ProtocolAuthorizationActionRulesNotFound = 'ProtocolAuthorizationActionRulesNotFound',
58-
ProtocolAuthorizationExpiryReached = 'ProtocolAuthorizationExpiryReached',
58+
ProtocolAuthorizationExpirationPassed = 'ProtocolAuthorizationExpirationPassed',
5959
ProtocolAuthorizationIncorrectDataFormat = 'ProtocolAuthorizationIncorrectDataFormat',
6060
ProtocolAuthorizationIncorrectContextId = 'ProtocolAuthorizationIncorrectContextId',
6161
ProtocolAuthorizationIncorrectProtocolPath = 'ProtocolAuthorizationIncorrectProtocolPath',
@@ -75,7 +75,9 @@ export enum DwnErrorCode {
7575
ProtocolAuthorizationRoleMissingRecipient = 'ProtocolAuthorizationRoleMissingRecipient',
7676
ProtocolsConfigureDuplicateActorInRuleSet = 'ProtocolsConfigureDuplicateActorInRuleSet',
7777
ProtocolsConfigureDuplicateRoleInRuleSet = 'ProtocolsConfigureDuplicateRoleInRuleSet',
78-
ProtocolsConfigureInvalidExpiry = 'ProtocolsConfigureInvalidExpiry',
78+
ProtocolsConfigureInvalidExpiration = 'ProtocolsConfigureInvalidExpiration',
79+
ProtocolsConfigureInvalidExpirationDuration = 'ProtocolsConfigureInvalidExpirationDuration',
80+
ProtocolsConfigureInvalidExpirationDatetime = 'ProtocolsConfigureInvalidExpirationDatetime',
7981
ProtocolsConfigureInvalidSize = 'ProtocolsConfigureInvalidSize',
8082
ProtocolsConfigureInvalidActionMissingOf = 'ProtocolsConfigureInvalidActionMissingOf',
8183
ProtocolsConfigureInvalidActionOfNotAllowed = 'ProtocolsConfigureInvalidActionOfNotAllowed',

src/core/protocol-authorization.ts

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ export class ProtocolAuthorization {
159159
);
160160

161161
// Verify expiry
162-
ProtocolAuthorization.verifyExpiry(incomingMessage, ruleSet)
162+
ProtocolAuthorization.verifyExpiration(incomingMessage, ruleSet);
163163
}
164164

165165
public static async authorizeQueryOrSubscribe(
@@ -691,29 +691,48 @@ export class ProtocolAuthorization {
691691
}
692692

693693
/**
694-
* Verifies that reads adhere to the $expiry constraint if provided
695-
* @throws {Error} if expiry date is passed.
696-
*/
697-
private static verifyExpiry(
698-
incomingMessage: RecordsRead,
694+
* Verifies that queries and reads adhere to the $expiration constraint if provided
695+
* @throws {Error} if more than one $expiration property is set,
696+
*/
697+
private static verifyExpiration(
698+
incomingMessage: RecordsWrite,
699699
ruleSet: ProtocolRuleSet
700700
): void {
701-
const ruleExpiry = ruleSet.$expiry;
702-
if (!ruleExpiry) {
701+
const ruleExpiration = ruleSet.$expiration;
702+
if (!ruleExpiration) {
703703
return;
704704
}
705705

706-
const dateCreated = incomingMessage.message.descriptor.filter?.dateCreated;
707-
if (!dateCreated) {
708-
return;
706+
const expirationEntries = Object.entries(ruleExpiration);
707+
if (expirationEntries.length > 1) {
708+
throw new DwnError(DwnErrorCode.ProtocolsConfigureInvalidExpiration,
709+
`invalid property: expiration ${ruleExpiration} cannot set more than one property`);
709710
}
710711

711-
const dateExpiry = dateCreated + ruleExpiry;
712-
if (Date.now() > dateExpiry) {
713-
throw new DwnError(DwnErrorCode.ProtocolAuthorizationExpiryReached, `dateExpiry ${dateExpiry} has passed`);
712+
const { duration, datetime } = ruleExpiration;
713+
if (!duration && !datetime) {
714+
throw new DwnError(DwnErrorCode.ProtocolsConfigureInvalidExpiration, `invalid property ${ruleExpiration}: must set at least one property`);
714715
}
715716

716-
}
717+
if (duration && typeof duration === 'number' && duration < 1) {
718+
throw new DwnError(DwnErrorCode.ProtocolsConfigureInvalidExpirationDuration, `invalid property: duration ${duration} number must must be >= 1`);
719+
} else if (typeof duration === 'string') {
720+
const [amount, unit] = duration.split('')[0];
721+
if ((unit === 's' && parseInt(amount) < 1)) {
722+
throw new DwnError(DwnErrorCode.ProtocolsConfigureInvalidExpirationDuration,
723+
`invalid property: if duration unit ${unit} = s, amount ${amount} must >= 1 (i.e. 1s)`);
724+
}
725+
if (!/\d{1,}(s|m|h|d|y)/.test(duration)) {
726+
throw new DwnError(DwnErrorCode.ProtocolsConfigureInvalidExpirationDuration,
727+
`invalid property: duration ${duration} format must be \"<amount><s|m|h|d|y>\" (e.g. 1s, 10d, 5y)`);
728+
}
729+
}
730+
731+
if (datetime && /(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])T([01]\d|2[0-3]):([0-5]\d):([0-5]\d)Z/.test(datetime)) {
732+
throw new DwnError(DwnErrorCode.ProtocolsConfigureInvalidExpirationDatetime,
733+
`invalid format: datetime ${datetime} does not conform to ISO-8601 UTC format`);
734+
}
735+
};
717736

718737
/**
719738
* If the given RecordsWrite is not a role record, this method does nothing and succeeds immediately.

src/types/protocols-types.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,12 @@ export type ProtocolRuleSet = {
129129
}
130130

131131
/**
132-
* If $expiry is set, the record expiry in ms.
132+
* If $expiration is set, the record expiration in ms.
133133
*/
134-
$expiry?: number;
134+
$expiration?: {
135+
duration?: string | number;
136+
datetime?: string;
137+
};
135138

136139
// JSON Schema verifies that properties other than properties prefixed with $ will actually have type ProtocolRuleSet
137140
[key: string]: any;

0 commit comments

Comments
 (0)