Skip to content

Commit

Permalink
Improve error handling an heading mandates (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucemans authored Sep 23, 2024
1 parent 989afa7 commit 6df8d2f
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 36 deletions.
116 changes: 95 additions & 21 deletions app/src/specs/validateContent.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
/* eslint-disable sonarjs/cognitive-complexity */
/* eslint-disable unicorn/consistent-function-scoping */
import type { Node, Parent } from 'unist';

import { TracedError } from '../util/error';

const HEADINGS = [
{ title: /Abstract/, required: true, slug: 'abstract' },
{ title: /Motivation/, required: true, slug: 'motivation' },
{ title: /Specification/, required: true, slug: 'specification' },
{ title: /Rationale/, required: false, slug: 'rationale' },
{
title: /Backwards Compatibility/,
required: false,
slug: 'backwards-compatibility',
},
{
title: /Security Considerations/,
required: false,
slug: 'security-considerations',
},
{
title: /Appendix [\dA-Z]+: \w+/,
required: false,
allow_repeat: true,
slug: 'appendix',
},
{ title: /Copyright/, required: true, slug: 'copyright' },
];

export const validateHeadings = (
headings: {
type: 'heading';
Expand All @@ -16,41 +41,90 @@ export const validateHeadings = (
ignoredRules: string[],
directPath: string
) => {
const requiredHeadings = [
'Abstract',
'Motivation',
'Specification',
'Copyright',
].filter((heading) => !ignoredRules.includes(`missing:${heading}`));
let requiredHeadings = [...HEADINGS];

// Validate headings
for (const heading of headings) {
const [{ value }] = heading.children;
let found = false;

const newHeadings = [...requiredHeadings];

for (const requiredHeading of requiredHeadings) {
const match = requiredHeading.title.test(value);

console.log('->', match, requiredHeading.title.source);

if (match) {
// Found heading, nice
console.log(`Found heading \`${value}\``);
found = true;

if (!requiredHeading.allow_repeat && requiredHeading.required) {
newHeadings.splice(newHeadings.indexOf(requiredHeading), 1);
}

break;
}

if (requiredHeadings.includes(value)) {
if (value == requiredHeadings[0]) {
requiredHeadings.shift();
} else {
// If we are allowed to bypass by exemption
if (
ignoredRules.includes(
`heading:${value.toLowerCase().replace(/\s/g, '-')}`
)
) {
console.log('Ignoring supplemental heading due to rule');
found = true;
break;
}

if (requiredHeading.required) {
// If we are allowed to bypass requirement
if (ignoredRules.includes(`missing:${requiredHeading.slug}`)) {
console.log('Ignoring missing heading due to rule');
newHeadings.splice(newHeadings.indexOf(requiredHeading), 1);
continue;
}

// Expected this heading, required, not found
throw new TracedError(
`Expected ${requiredHeadings[0]} but found ${value}`,
`Unexpected heading \`${value}\`, expecting \`${requiredHeading.title.source}\``,
directPath,
heading.position.start.line,
heading.position.start.column,
heading.position.end.column
);
}
}

if (!found) {
console.log(requiredHeadings);
// Unexpected heading
throw new TracedError(
`Unexpected heading \`${value}\``,
directPath,
heading.position.start.line,
heading.position.start.column,
heading.position.end.column
);
}

requiredHeadings = newHeadings;
}

if (requiredHeadings.length > 0) {
throw new TracedError(
`Missing required heading${
requiredHeadings.length === 1 ? '' : 's'
} ${requiredHeadings.join(', ')}.`,
directPath,
0,
0,
0
);
for (const requiredHeading of requiredHeadings) {
if (
requiredHeading.required &&
!ignoredRules.includes(`missing:${requiredHeading.slug}`)
) {
throw new TracedError(
`Missing required heading \`${requiredHeading.title.source}\``,
directPath,
0,
0,
0
);
}
}
};

Expand Down
2 changes: 1 addition & 1 deletion ensips/1.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ contributors:
ensip:
created: '2016-04-04'
status: final
ignoredRules: ["missing:Copyright"]
ignoredRules: ["missing:copyright"]
---

# ENSIP-1: ENS
Expand Down
2 changes: 1 addition & 1 deletion ensips/12.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Clients SHOULD additionally take the following verification steps:

Clients MAY support NFT URIs by rewriting them to `https` URIs for a service that provides NFT avatar image resolution support.

## Examples
### Examples

The following examples all resolve to the same avatar image:

Expand Down
12 changes: 6 additions & 6 deletions ensips/13.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ contributors:
ensip:
created: 2021-08-03
status: draft
ignoredRules: ["missing:Specification"]
ignoredRules: ["missing:specification"]
---

# ENSIP-13: SAFE Authentication For ENS
Expand Down Expand Up @@ -115,9 +115,9 @@ The reason for this design choice is to allow for simplicity of authentication v

Further, you can design UX without any user interaction necessary to 'pick' the interacting address by display assets owned by `authAddress` and `mainAddress` and use the appropriate address dependent on the asset the user is attempting to authenticate with.

## Reference Implementation
### Reference Implementation

### Client/Server Side
#### Client/Server Side

In typescript, the validation function, using ethers.js would be as follows:

Expand Down Expand Up @@ -163,13 +163,13 @@ export async function getLinkedAddress(
}
```

### Contract side
#### Contract side

#### With a backend
##### With a backend

If your application operates a secure backend server, you could run the client/server code above, then use the result in conjunction with specs like [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) : `Standard Signature Validation Method for Contracts` for a cheap and secure way to validate that the the message signer is indeed authenticated for the main address.

#### Without a backend (JavaScript only)
##### Without a backend (JavaScript only)

Provided is a reference implementation for an internal function to verify that the message sender has an authentication link to the main address.

Expand Down
2 changes: 1 addition & 1 deletion ensips/14.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ contributors:
ensip:
status: draft
created: 2021-02-07
ignoredRules: ["missing:Motivation", "missing:Copyright"]
ignoredRules: ["missing:motivation", "missing:copyright", "heading:user-referral-data", "heading:privacy-concerns", "heading:a-reverse-code-registry"]
---

# ENSIP-14: On Chain Source Parameter
Expand Down
1 change: 1 addition & 0 deletions ensips/15.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ contributors:
ensip:
status: draft
created: 2023-04-03
ignoredRules: ["heading:description-of-", "heading:derivation", "heading:appendix:-reference-specifications", "heading:appendix:-additional-resources", "heading:appendix:-validation-tests", "heading:annex:-beautification"]
---

# ENSIP-15: ENS Name Normalization Standard
Expand Down
1 change: 1 addition & 0 deletions ensips/16.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ contributors:
ensip:
status: draft
created: 2022-09-22
ignoredRules: ["heading:implementation", "heading:open-items"]
---

# ENSIP-16: Offchain Metadata
Expand Down
2 changes: 1 addition & 1 deletion ensips/2.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ contributors:
ensip:
created: '2016-10-25'
status: obsolete
ignoredRules: ["missing:Copyright"]
ignoredRules: ["heading:prior-work"]
---

# ENSIP-2: Initial Hash Registrar
Expand Down
3 changes: 1 addition & 2 deletions ensips/3.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ contributors:
ensip:
created: '2016-12-01'
status: final
ignoredRules: ["missing:Copyright"]
---

# ENSIP-3: Reverse Resolution
Expand Down Expand Up @@ -219,6 +218,6 @@ contract ReverseRegistrar {
}
```

### Copyright
## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
2 changes: 1 addition & 1 deletion ensips/4.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ contributors:
ensip:
created: '2017-02-06'
status: final
ignoredRules: ["", "", "missing:Motivation"]
ignoredRules: ["missing:motivation"]
---

# ENSIP-4: Support for contract ABIs
Expand Down
3 changes: 2 additions & 1 deletion ensips/6.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ contributors:
ensip:
created: '2018-06-26'
status: obsolete
ignoredRules: ["heading:implementation", "heading:test-cases"]
---

# ENSIP-6: DNS-in-ENS
Expand Down Expand Up @@ -73,7 +74,7 @@ The arguments for the function are as follows:

The function returns `true` if there are any records for the provided node and name, otherwise `false`.

## Backwards compatibility
## Backwards Compatibility

Not applicable.

Expand Down
1 change: 1 addition & 0 deletions ensips/8.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ contributors:
ensip:
created: '2019-03-05'
status: final
ignoredRules: ["heading:implementation"]
---

# ENSIP-8: Interface Discovery
Expand Down
2 changes: 1 addition & 1 deletion ensips/9.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ contributors:
ensip:
created: 2019-09-09
status: final
ignoredRules: ["missing:Abstract"]
ignoredRules: ["missing:abstract", "heading:tests"]
---

# ENSIP-9: Multichain Address resolution
Expand Down

0 comments on commit 6df8d2f

Please sign in to comment.