diff --git a/dev/Sieve/Extensions/rfc5183.js b/dev/Sieve/Extensions/rfc5183.js index 943f17f01..1279f1f48 100644 --- a/dev/Sieve/Extensions/rfc5183.js +++ b/dev/Sieve/Extensions/rfc5183.js @@ -30,7 +30,7 @@ export class EnvironmentTest extends GrammarTest pushArguments(args) { - this.name = args[args.length-2]; - this.key_list = args[args.length-1]; + this.key_list = args.pop(); + this.name = args.pop(); } } diff --git a/dev/Sieve/Extensions/rfc5229.js b/dev/Sieve/Extensions/rfc5229.js index 9076125d6..08b4aea8e 100644 --- a/dev/Sieve/Extensions/rfc5229.js +++ b/dev/Sieve/Extensions/rfc5229.js @@ -40,8 +40,8 @@ export class SetCommand extends GrammarCommand [':lower', ':upper', ':lowerfirst', ':upperfirst', ':quotewildcard', ':length'].forEach(modifier => { args.includes(modifier) && this.modifiers.push(modifier); }); - this._name = args[args.length-2]; - this._value = args[args.length-1]; + this._value = args.pop(); + this._name = args.pop(); } } @@ -65,7 +65,7 @@ export class StringTest extends GrammarTest pushArguments(args) { - this.source = args[args.length-2]; - this.key_list = args[args.length-1]; + this.key_list = args.pop(); + this.source = args.pop(); } } diff --git a/dev/Sieve/Extensions/rfc5230.js b/dev/Sieve/Extensions/rfc5230.js index c0baed1a8..9178eb20b 100644 --- a/dev/Sieve/Extensions/rfc5230.js +++ b/dev/Sieve/Extensions/rfc5230.js @@ -70,30 +70,15 @@ export class VacationCommand extends GrammarCommand pushArguments(args) { + this._reason.value = args.pop().value; // GrammarQuotedString args.forEach((arg, i) => { if (':mime' === arg) { this.mime = true; - } else if (i === args.length-1) { - this._reason.value = arg.value; // GrammarQuotedString - } else switch (args[i-1]) { - case ':days': - this._days.value = arg.value; // GrammarNumber - break; -// case ':seconds': -// this._seconds.value = arg.value; // GrammarNumber -// break; - case ':subject': - this._subject.value = arg.value; // GrammarQuotedString - break; - case ':from': - this._from.value = arg.value; // GrammarQuotedString - break; - case ':addresses': - this.addresses = arg; // GrammarStringList - break; - case ':handle': - this._from.value = arg.value; // GrammarQuotedString - break; + } else if (':addresses' === args[i-1]) { + this.addresses = arg; // GrammarStringList + } else if (':' === args[i-1][0]) { + // :days, :seconds, :subject, :from, :handle + this[args[i-1].replace(':','_')].value = arg.value; } }); } diff --git a/dev/Sieve/Extensions/rfc5260.js b/dev/Sieve/Extensions/rfc5260.js index 03d6b6d2b..5c7868adc 100644 --- a/dev/Sieve/Extensions/rfc5260.js +++ b/dev/Sieve/Extensions/rfc5260.js @@ -41,7 +41,9 @@ export class DateTest extends GrammarTest pushArguments(args) { - let l = args.length - 1; + this.key_list = args.pop(); + this.date_part = args.pop(); + this.header_name = args.pop(); args.forEach((arg, i) => { if (':originalzone' === arg) { this.originalzone = true; @@ -51,12 +53,6 @@ export class DateTest extends GrammarTest this.zone.value = arg.value; } else if (':index' === args[i-1]) { this.index.value = arg.value; - } else if (l-2 === i) { - this.header_name = arg; - } else if (l-1 === i) { - this.date_part = arg; - } else if (l === i) { - this.key_list = arg; } }); } @@ -86,14 +82,11 @@ export class CurrentDateTest extends GrammarTest pushArguments(args) { - let l = args.length - 1; + this.key_list = args.pop(); + this.date_part = args.pop(); args.forEach((arg, i) => { if (':zone' === args[i-1]) { this.zone.value = arg.value; - } else if (l-1 === i) { - this.date_part = arg; - } else if (l === i) { - this.key_list = arg; } }); } diff --git a/dev/Sieve/Extensions/rfc5293.js b/dev/Sieve/Extensions/rfc5293.js index 3f39fd9ab..36411fb2d 100644 --- a/dev/Sieve/Extensions/rfc5293.js +++ b/dev/Sieve/Extensions/rfc5293.js @@ -32,9 +32,9 @@ export class AddHeaderCommand extends GrammarCommand pushArguments(args) { + this.value = args.pop(); + this.field_name = args.pop(); this.last = args.includes(':last'); - this.field_name = args[args.length - 2]; - this.value = args[args.length - 1]; } } diff --git a/dev/Sieve/Extensions/rfc5435.js b/dev/Sieve/Extensions/rfc5435.js new file mode 100644 index 000000000..4c1939456 --- /dev/null +++ b/dev/Sieve/Extensions/rfc5435.js @@ -0,0 +1,123 @@ +/** + * https://tools.ietf.org/html/rfc5435 + */ + +import { + GrammarCommand, + GrammarNumber, + GrammarQuotedString, + GrammarStringList, + GrammarTest +} from 'Sieve/Grammar'; + +/** + * https://datatracker.ietf.org/doc/html/rfc5435#section-3 + */ +export class NotifyCommand extends GrammarCommand +{ + constructor() + { + super(); + this._method = new GrammarQuotedString; + this._from = new GrammarQuotedString; + this._importance = new GrammarNumber; + this.options = new GrammarStringList; + this._message = new GrammarQuotedString; + } + + get method() { return this._method.value; } + get from() { return this._from.value; } + get importance() { return this._importance.value; } + get message() { return this._message.value; } + + set method(str) { this._method.value = str; } + set from(str) { this._from.value = str; } + set importance(int) { this._importance.value = int; } + set message(str) { this._message.value = str; } + + get require() { return 'enotify'; } + + toString() + { + let result = 'notify'; + if (this._from.value) { + result += ' :from ' + this._from; + } + if (0 < this._importance.value) { + result += ' :importance ' + this._importance; + } + if (this.options.length) { + result += ' :options ' + this.options; + } + if (this._message.value) { + result += ' :message ' + this._message; + } + return result + ' ' + this._method; + } + + pushArguments(args) + { + this._method.value = args.pop().value; // GrammarQuotedString + args.forEach((arg, i) => { + if (':options' === args[i-1]) { + this.options = arg; // GrammarStringList + } else if (':' === args[i-1][0]) { + // :from, :importance, :message + this[args[i-1].replace(':','_')].value = arg.value; + } + }); + } +} + +/** + * https://datatracker.ietf.org/doc/html/rfc5435#section-4 + */ +export class ValidNotifyMethodTest extends GrammarTest +{ + constructor() + { + super(); + this.notification_uris = new GrammarStringList; + } + + toString() + { + return 'valid_notify_method ' + this.notification_uris; + } + + pushArguments(args) + { + this.notification_uris = args.pop(); + } +} + +/** + * https://datatracker.ietf.org/doc/html/rfc5435#section-5 + */ +export class NotifyMethodCapabilityTest extends GrammarTest +{ + constructor() + { + super(); + this.notification_uri = new GrammarQuotedString; + this.notification_capability = new GrammarQuotedString; + this.key_list = new GrammarStringList; + } + + toString() + { + return 'valid_notify_method ' + + (this.comparator ? ' :comparator ' + this.comparator : '') + + (this.match_type ? ' ' + this.match_type : '') + + this.notification_uri + + this.notification_capability + + this.key_list; + } + + pushArguments(args) + { + this.key_list = args.pop(); + this.notification_capability = args.pop(); + this.notification_uri = args.pop(); + } +} diff --git a/dev/Sieve/Extensions/rfc5463.js b/dev/Sieve/Extensions/rfc5463.js index 9c9123875..967363d0b 100644 --- a/dev/Sieve/Extensions/rfc5463.js +++ b/dev/Sieve/Extensions/rfc5463.js @@ -5,7 +5,7 @@ import { GrammarCommand, GrammarTest, - GrammarString, + GrammarQuotedString, GrammarStringList } from 'Sieve/Grammar'; @@ -29,10 +29,7 @@ export class IHaveTest extends GrammarTest pushArguments(args) { - let l = args.length; - if (args[l-1] instanceof GrammarString) { - this.method = args[l-1]; - } + this.capabilities = args.pop(); } } @@ -44,7 +41,7 @@ export class ErrorCommand extends GrammarCommand constructor() { super(); - this.message = new GrammarString; + this.message = new GrammarQuotedString; } get require() { return 'ihave'; } @@ -56,9 +53,6 @@ export class ErrorCommand extends GrammarCommand pushArguments(args) { - let l = args.length; - if (args[l-1] instanceof GrammarString) { - this.method = args[l-1]; - } + this.message = args.pop(); } } diff --git a/dev/Sieve/Extensions/rfc5490.js b/dev/Sieve/Extensions/rfc5490.js index aa9409de3..aa836c813 100644 --- a/dev/Sieve/Extensions/rfc5490.js +++ b/dev/Sieve/Extensions/rfc5490.js @@ -4,7 +4,7 @@ import { GrammarTest, - GrammarString, + GrammarQuotedString, GrammarStringList } from 'Sieve/Grammar'; @@ -42,8 +42,8 @@ export class MetadataTest extends GrammarTest constructor() { super(); - this.mailbox = new GrammarString; - this.annotation_name = new GrammarString; + this.mailbox = new GrammarQuotedString; + this.annotation_name = new GrammarQuotedString; this.key_list = new GrammarStringList; } @@ -61,9 +61,9 @@ export class MetadataTest extends GrammarTest pushArguments(args) { - this.mailbox = args[args.length-3]; - this.annotation_name = args[args.length-2]; - this.key_list = args[args.length-1]; + this.key_list = args.pop(); + this.annotation_name = args.pop(); + this.mailbox = args.pop(); } } @@ -75,7 +75,7 @@ export class MetadataExistsTest extends GrammarTest constructor() { super(); - this.mailbox = new GrammarString; + this.mailbox = new GrammarQuotedString; this.annotation_names = new GrammarStringList; } @@ -90,8 +90,8 @@ export class MetadataExistsTest extends GrammarTest pushArguments(args) { - this.mailbox = args[args.length-2]; - this.annotation_names = args[args.length-1]; + this.annotation_names = args.pop(); + this.mailbox = args.pop(); } } @@ -103,7 +103,7 @@ export class ServerMetadataTest extends GrammarTest constructor() { super(); - this.annotation_name = new GrammarString; + this.annotation_name = new GrammarQuotedString; this.key_list = new GrammarStringList; } @@ -120,8 +120,8 @@ export class ServerMetadataTest extends GrammarTest pushArguments(args) { - this.annotation_name = args[args.length-2]; - this.key_list = args[args.length-1]; + this.key_list = args.pop(); + this.annotation_name = args.pop(); } } @@ -146,6 +146,6 @@ export class ServerMetadataExistsTest extends GrammarTest pushArguments(args) { - this.annotation_names = args[args.length-1]; + this.annotation_names = args.pop(); } } diff --git a/dev/Sieve/Parser.js b/dev/Sieve/Parser.js index 2ed9fdd3f..cbc2587a7 100644 --- a/dev/Sieve/Parser.js +++ b/dev/Sieve/Parser.js @@ -69,6 +69,7 @@ import { SpamTestTest, VirusTestTest } from 'Sieve/Extensions/rfc5235'; import { DateTest, CurrentDateTest } from 'Sieve/Extensions/rfc5260'; import { AddHeaderCommand, DeleteHeaderCommand } from 'Sieve/Extensions/rfc5293'; import { ErejectCommand, RejectCommand } from 'Sieve/Extensions/rfc5429'; +import { NotifyCommand, ValidNotifyMethodTest, NotifyMethodCapabilityTest } from 'Sieve/Extensions/rfc5435'; import { IHaveTest, ErrorCommand } from 'Sieve/Extensions/rfc5463'; import { MailboxExistsTest, MetadataTest, MetadataExistsTest } from 'Sieve/Extensions/rfc5490'; import { IncludeCommand, ReturnCommand } from 'Sieve/Extensions/rfc6609'; @@ -124,6 +125,10 @@ const // rfc5429 ereject: ErejectCommand, reject: RejectCommand, + // rfc5435 + notify: NotifyCommand, + valid_notify_method: ValidNotifyMethodTest, + notify_method_capability: NotifyMethodCapabilityTest, // rfc5463 ihave: IHaveTest, error: ErrorCommand, diff --git a/dev/Sieve/README.md b/dev/Sieve/README.md index 0c24b4d3b..4252b5446 100644 --- a/dev/Sieve/README.md +++ b/dev/Sieve/README.md @@ -16,7 +16,7 @@ https://www.iana.org/assignments/sieve-extensions/sieve-extensions.xhtml - [x] RFC5260 date / index - [x] RFC5293 editheader - [x] RFC5429 ereject / reject -- [ ] RFC5435 enotify +- [x] RFC5435 enotify - [x] RFC5463 ihave - [x] RFC5490 mailbox / mboxmetadata / servermetadata - [ ] RFC5703 enclose / extracttext / foreverypart / mime / replace