Skip to content

Commit

Permalink
chore: fix lint errors
Browse files Browse the repository at this point in the history
  • Loading branch information
jeswr committed Nov 14, 2023
1 parent 616eef2 commit 8bc8d3e
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 76 deletions.
46 changes: 37 additions & 9 deletions src/common/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
import { Term, Quad, NamedNode, BlankNode, Literal } from "@rdfjs/types";
//
// Copyright Inrupt Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
// Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
import type { Term, Quad, NamedNode, BlankNode, Literal } from "@rdfjs/types";
import { DataFactory } from "n3";
import { rdf } from "rdf-namespaces";

const { namedNode } = DataFactory;

export const cred = "https://www.w3.org/2018/credentials#";
Expand All @@ -24,16 +45,23 @@ export const APPEND = namedNode(`${acl}Append`);
export const ISSUANCE_DATE = namedNode(`${cred}issuanceDate`);
export const EXPIRATION_DATE = namedNode(`${cred}expirationDate`);
export const ISSUER = namedNode(`${cred}issuer`);
export const INHERIT = namedNode("urn:uuid:71ab2f68-a68b-4452-b968-dd23e0570227");
export const INHERIT = namedNode(
"urn:uuid:71ab2f68-a68b-4452-b968-dd23e0570227",
);

export function assertTermType(term: Term): NamedNode
export function assertTermType(term: Term, type: 'NamedNode'): NamedNode
export function assertTermType(term: Term, type: 'BlankNode'): BlankNode
export function assertTermType(term: Term, type: 'Literal'): Literal
export function assertTermType(term: Term, type?: Term['termType']): Term
export function assertTermType(term: Term, type: Term['termType'] = 'NamedNode'): Term {
export function assertTermType(term: Term): NamedNode;
export function assertTermType(term: Term, type: "NamedNode"): NamedNode;
export function assertTermType(term: Term, type: "BlankNode"): BlankNode;
export function assertTermType(term: Term, type: "Literal"): Literal;
export function assertTermType(term: Term, type?: Term["termType"]): Term;
export function assertTermType(
term: Term,
type: Term["termType"] = "NamedNode",
): Term {
if (term.termType !== type) {
throw new Error(`Expected [${term.value}] to be a ${type}. Found ${term.termType}`);
throw new Error(
`Expected [${term.value}] to be a ${type}. Found ${term.termType}`,
);
}
return term;
}
Expand Down
44 changes: 32 additions & 12 deletions src/common/getters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,19 +172,29 @@ describe("getIssuanceDate", () => {
describe("gConsent data model", () => {
it("gets the gConsent access issuance date", async () => {
const issuanceDate = new Date().toString();
const gConsentGrant = await mockGConsentGrant(undefined, undefined, o => {
o.issuanceDate = issuanceDate;
});
const gConsentGrant = await mockGConsentGrant(
undefined,
undefined,
(obj) => {
// eslint-disable-next-line no-param-reassign
obj.issuanceDate = issuanceDate;
},
);
expect(getIssuanceDate(gConsentGrant)).toStrictEqual(
new Date(issuanceDate),
);
});

it("gets the gConsent access request issuance date", async () => {
const issuanceDate = new Date().toString();
const gConsentRequest = await mockGConsentRequest(undefined, undefined, o => {
o.issuanceDate = issuanceDate;
});
const gConsentRequest = await mockGConsentRequest(
undefined,
undefined,
(obj) => {
// eslint-disable-next-line no-param-reassign
obj.issuanceDate = issuanceDate;
},
);
expect(getIssuanceDate(gConsentRequest)).toStrictEqual(
new Date(issuanceDate),
);
Expand All @@ -196,19 +206,29 @@ describe("getExpirationDate", () => {
describe("gConsent data model", () => {
it("gets the gConsent access expiration date", async () => {
const expirationDate = new Date().toString();
const gConsentGrant = await mockGConsentGrant(undefined, undefined, o => {
o.expirationDate = expirationDate;
});
const gConsentGrant = await mockGConsentGrant(
undefined,
undefined,
(obj) => {
// eslint-disable-next-line no-param-reassign
obj.expirationDate = expirationDate;
},
);
expect(getExpirationDate(gConsentGrant)).toStrictEqual(
new Date(expirationDate),
);
});

it("gets the gConsent access request expiration date", async () => {
const expirationDate = new Date().toString();
const gConsentRequest = await mockGConsentRequest(undefined, undefined, o => {
o.expirationDate = expirationDate;
});
const gConsentRequest = await mockGConsentRequest(
undefined,
undefined,
(obj) => {
// eslint-disable-next-line no-param-reassign
obj.expirationDate = expirationDate;
},
);
expect(getExpirationDate(gConsentRequest)).toStrictEqual(
new Date(expirationDate),
);
Expand Down
137 changes: 110 additions & 27 deletions src/common/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,36 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
import { BlankNode, DatasetCore, Literal, NamedNode, Quad_Subject, Term } from "@rdfjs/types";
import type {
BlankNode,
DatasetCore,
Literal,
NamedNode,
Term,
} from "@rdfjs/types";
import { DataFactory } from "n3";
import { isAccessGrant as isGConsentAccessGrant } from "../gConsent/guard/isAccessGrant";
import type { AccessGrantGConsent } from "../gConsent/type/AccessGrant";
import type { AccessRequestGConsent } from "../gConsent/type/AccessRequest";
import type { AccessModes } from "../type/AccessModes";
import { APPEND, CREDENTIAL_SUBJECT, EXPIRATION_DATE, HAS_CONSENT, INHERIT, ISSUANCE_DATE, ISSUER, IS_PROVIDED_TO, MODE, PROVIDED_CONSENT, READ, WRITE, XSD_BOOLEAN, assertTermType, getSingleQuad } from "./constants";
import {
APPEND,
CREDENTIAL_SUBJECT,
EXPIRATION_DATE,
HAS_CONSENT,
INHERIT,
ISSUANCE_DATE,
ISSUER,
IS_PROVIDED_TO,
MODE,
PROVIDED_CONSENT,
READ,
WRITE,
XSD_BOOLEAN,
assertTermType,
getSingleQuad,
} from "./constants";

const { namedNode, defaultGraph, quad, literal } = DataFactory;

/**
Expand Down Expand Up @@ -60,9 +83,7 @@ export function getResources(
* @param vc The Access Grant/Request
* @returns The resource owner WebID
*/
export function getResourceOwner(
vc: AccessGrantGConsent,
): string;
export function getResourceOwner(vc: AccessGrantGConsent): string;
export function getResourceOwner(
vc: AccessGrantGConsent | AccessRequestGConsent,
): string | undefined;
Expand Down Expand Up @@ -90,19 +111,51 @@ export function getResourceOwner(
export function getRequestor(
vc: AccessGrantGConsent | AccessRequestGConsent,
): string {
const credentialSubject = getSingleObject(vc, namedNode(vc.id), CREDENTIAL_SUBJECT);
const credentialSubject = getSingleObject(

Check warning on line 114 in src/common/getters.ts

View workflow job for this annotation

GitHub Actions / lint / lint

'getSingleObject' was used before it was defined
vc,
namedNode(vc.id),
CREDENTIAL_SUBJECT,
);
if (isGConsentAccessGrant(vc)) {
const providedConsent = getSingleObject(vc, credentialSubject, PROVIDED_CONSENT, 'BlankNode');
const providedConsent = getSingleObject(

Check warning on line 120 in src/common/getters.ts

View workflow job for this annotation

GitHub Actions / lint / lint

'getSingleObject' was used before it was defined
vc,
credentialSubject,
PROVIDED_CONSENT,
"BlankNode",
);
return getSingleObject(vc, providedConsent, IS_PROVIDED_TO).value;

Check warning on line 126 in src/common/getters.ts

View workflow job for this annotation

GitHub Actions / lint / lint

'getSingleObject' was used before it was defined
}
return credentialSubject.value;
}

function getSingleObject<T extends Term['termType']>(vc: DatasetCore, subject: Term, predicate: Term): NamedNode;
function getSingleObject<T extends Term['termType']>(vc: DatasetCore, subject: Term, predicate: Term, type: 'BlankNode'): BlankNode;
function getSingleObject<T extends Term['termType']>(vc: DatasetCore, subject: Term, predicate: Term, type: 'Literal'): Literal;
function getSingleObject<T extends Term['termType']>(vc: DatasetCore, subject: Term, predicate: Term, type?: T) {
return assertTermType(getSingleQuad([...vc.match(subject, predicate, null, defaultGraph())]).object, type);
function getSingleObject(
vc: DatasetCore,
subject: Term,
predicate: Term,
): NamedNode;
function getSingleObject(
vc: DatasetCore,
subject: Term,
predicate: Term,
type: "BlankNode",
): BlankNode;
function getSingleObject(
vc: DatasetCore,
subject: Term,
predicate: Term,
type: "Literal",
): Literal;
function getSingleObject(
vc: DatasetCore,
subject: Term,
predicate: Term,
type?: Term["termType"],
) {
return assertTermType(
getSingleQuad([...vc.match(subject, predicate, null, defaultGraph())])
.object,
type,
);
}

/**
Expand All @@ -120,8 +173,17 @@ function getSingleObject<T extends Term['termType']>(vc: DatasetCore, subject: T
export function getAccessModes(
vc: AccessGrantGConsent | AccessRequestGConsent,
): AccessModes {
const credentialSubject = getSingleObject(vc, namedNode(vc.id), CREDENTIAL_SUBJECT);
const consent = getSingleObject(vc, credentialSubject, isGConsentAccessGrant(vc) ? PROVIDED_CONSENT : HAS_CONSENT, 'BlankNode');
const credentialSubject = getSingleObject(
vc,
namedNode(vc.id),
CREDENTIAL_SUBJECT,
);
const consent = getSingleObject(
vc,
credentialSubject,
isGConsentAccessGrant(vc) ? PROVIDED_CONSENT : HAS_CONSENT,
"BlankNode",
);
return {
read: vc.has(quad(consent, MODE, READ, defaultGraph())),
write: vc.has(quad(consent, MODE, WRITE, defaultGraph())),
Expand All @@ -141,9 +203,7 @@ export function getAccessModes(
* @param vc The Access Grant/Request
* @returns The VC ID URL
*/
export function getId(
vc: AccessGrantGConsent | AccessRequestGConsent,
): string {
export function getId(vc: AccessGrantGConsent | AccessRequestGConsent): string {
return vc.id;
}

Expand All @@ -166,10 +226,16 @@ export function getTypes(
}

function wrapDate(date: Literal) {
if (!date.datatype.equals(namedNode('http://www.w3.org/2001/XMLSchema#dateTime'))) {
throw new Error(`Expected date to be a dateTime; recieved [${date.datatype.value}]`);
if (
!date.datatype.equals(
namedNode("http://www.w3.org/2001/XMLSchema#dateTime"),
)
) {
throw new Error(
`Expected date to be a dateTime; recieved [${date.datatype.value}]`,
);
}
return new Date(date.value);
return new Date(date.value);
}

/**
Expand All @@ -187,7 +253,9 @@ function wrapDate(date: Literal) {
export function getIssuanceDate(
vc: AccessGrantGConsent | AccessRequestGConsent,
): Date {
return wrapDate(getSingleObject(vc, namedNode(vc.id), ISSUANCE_DATE, 'Literal'));
return wrapDate(
getSingleObject(vc, namedNode(vc.id), ISSUANCE_DATE, "Literal"),
);
}

/**
Expand All @@ -205,14 +273,18 @@ export function getIssuanceDate(
export function getExpirationDate(
vc: AccessGrantGConsent | AccessRequestGConsent,
): Date | undefined {
const expirationDate = [...vc.match(namedNode(vc.id), EXPIRATION_DATE, null, defaultGraph())];
const expirationDate = [
...vc.match(namedNode(vc.id), EXPIRATION_DATE, null, defaultGraph()),
];

if (expirationDate.length > 1) {
throw new Error(`Expected at most one expiration date. Found ${expirationDate.length}`);
throw new Error(
`Expected at most one expiration date. Found ${expirationDate.length}`,
);
}

if (expirationDate.length === 1) {
return wrapDate(assertTermType(expirationDate[0].object, 'Literal'));
return wrapDate(assertTermType(expirationDate[0].object, "Literal"));
}

return undefined;
Expand Down Expand Up @@ -251,9 +323,20 @@ export function getIssuer(
export function getInherit(
vc: AccessGrantGConsent | AccessRequestGConsent,
): boolean {
const credentialSubject = getSingleObject(vc, namedNode(vc.id), CREDENTIAL_SUBJECT);
const consent = getSingleObject(vc, credentialSubject, isGConsentAccessGrant(vc) ? PROVIDED_CONSENT : HAS_CONSENT, 'BlankNode');
return !vc.has(quad(consent, INHERIT, literal('false', XSD_BOOLEAN), defaultGraph()));
const credentialSubject = getSingleObject(
vc,
namedNode(vc.id),
CREDENTIAL_SUBJECT,
);
const consent = getSingleObject(
vc,
credentialSubject,
isGConsentAccessGrant(vc) ? PROVIDED_CONSENT : HAS_CONSENT,
"BlankNode",
);
return !vc.has(
quad(consent, INHERIT, literal("false", XSD_BOOLEAN), defaultGraph()),
);
}

/**
Expand Down
11 changes: 7 additions & 4 deletions src/common/verify/isValidAccessGrant.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import type * as CrossFetch from "@inrupt/universal-fetch";
import {
isVerifiableCredential,
getVerifiableCredentialApiConfiguration,
verifiableCredentialToDataset,
// verifiableCredentialToDataset,
} from "@inrupt/solid-client-vc";

import type * as VcLibrary from "@inrupt/solid-client-vc";
Expand All @@ -41,9 +41,9 @@ jest.mock("@inrupt/solid-client", () => {
});

jest.mock("@inrupt/solid-client-vc", () => {
const { verifiableCredentialToDataset } = jest.requireActual(
"@inrupt/solid-client-vc",
) as jest.Mocked<typeof VcLibrary>;
const { verifiableCredentialToDataset } = jest.requireActual<
typeof VcLibrary
>("@inrupt/solid-client-vc");
return {
verifiableCredentialToDataset,
isVerifiableCredential: jest.fn(),
Expand Down Expand Up @@ -97,6 +97,9 @@ describe("isValidAccessGrant", () => {
let MOCK_ACCESS_GRANT: VcLibrary.VerifiableCredential;

beforeAll(async () => {
const { verifiableCredentialToDataset } = jest.requireActual<
typeof VcLibrary
>("@inrupt/solid-client-vc");
MOCK_ACCESS_GRANT = await verifiableCredentialToDataset(
MOCK_ACCESS_GRANT_BASE,
);
Expand Down
Loading

0 comments on commit 8bc8d3e

Please sign in to comment.