solid-logic 1.3.17-f7bdc345 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +0 -0
- package/.eslintrc.js +0 -0
- package/.github/workflows/ci.yml +0 -0
- package/.github/workflows/release.yml +0 -0
- package/.nvmrc +0 -0
- package/LICENSE +0 -0
- package/README.md +0 -0
- package/jest.config.js +0 -0
- package/lib/acl/aclLogic.d.ts +3 -30
- package/lib/acl/aclLogic.d.ts.map +1 -1
- package/lib/acl/aclLogic.js +152 -119
- package/lib/acl/aclLogic.js.map +1 -1
- package/lib/authSession/authSession.d.ts +0 -0
- package/lib/authSession/authSession.d.ts.map +0 -0
- package/lib/authSession/authSession.js +0 -0
- package/lib/authSession/authSession.js.map +0 -0
- package/lib/authn/SolidAuthnLogic.d.ts +0 -0
- package/lib/authn/SolidAuthnLogic.d.ts.map +1 -1
- package/lib/authn/SolidAuthnLogic.js +2 -2
- package/lib/authn/SolidAuthnLogic.js.map +1 -1
- package/lib/authn/authUtil.d.ts +0 -0
- package/lib/authn/authUtil.d.ts.map +0 -0
- package/lib/authn/authUtil.js +0 -0
- package/lib/authn/authUtil.js.map +0 -0
- package/lib/chat/chatLogic.d.ts +3 -0
- package/lib/chat/chatLogic.d.ts.map +1 -0
- package/lib/chat/{ChatLogic.js → chatLogic.js} +82 -86
- package/lib/chat/chatLogic.js.map +1 -0
- package/lib/inbox/inboxLogic.d.ts +3 -0
- package/lib/inbox/inboxLogic.d.ts.map +1 -0
- package/lib/inbox/{InboxLogic.js → inboxLogic.js} +58 -64
- package/lib/inbox/inboxLogic.js.map +1 -0
- package/lib/index.d.ts +6 -11
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -38
- package/lib/index.js.map +1 -1
- package/lib/issuer/issuerLogic.d.ts +0 -0
- package/lib/issuer/issuerLogic.d.ts.map +0 -0
- package/lib/issuer/issuerLogic.js +1 -1
- package/lib/issuer/issuerLogic.js.map +1 -1
- package/lib/logic/CustomError.d.ts +4 -0
- package/lib/logic/CustomError.d.ts.map +1 -1
- package/lib/logic/CustomError.js +17 -1
- package/lib/logic/CustomError.js.map +1 -1
- package/lib/logic/solidLogic.d.ts +6 -0
- package/lib/logic/solidLogic.d.ts.map +1 -0
- package/lib/logic/solidLogic.js +92 -0
- package/lib/logic/solidLogic.js.map +1 -0
- package/lib/logic/solidLogicSingleton.d.ts +1 -2
- package/lib/logic/solidLogicSingleton.d.ts.map +1 -1
- package/lib/logic/solidLogicSingleton.js +3 -3
- package/lib/logic/solidLogicSingleton.js.map +1 -1
- package/lib/profile/profileLogic.d.ts +3 -0
- package/lib/profile/profileLogic.d.ts.map +1 -0
- package/lib/profile/profileLogic.js +246 -0
- package/lib/profile/profileLogic.js.map +1 -0
- package/lib/typeIndex/typeIndexLogic.d.ts +2 -21
- package/lib/typeIndex/typeIndexLogic.d.ts.map +1 -1
- package/lib/typeIndex/typeIndexLogic.js +304 -296
- package/lib/typeIndex/typeIndexLogic.js.map +1 -1
- package/lib/types.d.ts +82 -1
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +0 -0
- package/lib/types.js.map +0 -0
- package/lib/util/containerLogic.d.ts +11 -0
- package/lib/util/containerLogic.d.ts.map +1 -0
- package/lib/{profile/ProfileLogic.js → util/containerLogic.js} +53 -44
- package/lib/util/containerLogic.js.map +1 -0
- package/lib/util/debug.d.ts +0 -0
- package/lib/util/debug.d.ts.map +0 -0
- package/lib/util/debug.js +0 -0
- package/lib/util/debug.js.map +0 -0
- package/lib/util/ns.d.ts +2 -0
- package/lib/util/ns.d.ts.map +1 -0
- package/lib/util/ns.js +34 -0
- package/lib/util/ns.js.map +1 -0
- package/lib/util/utilityLogic.d.ts +15 -0
- package/lib/util/utilityLogic.d.ts.map +1 -0
- package/lib/util/utilityLogic.js +272 -0
- package/lib/util/utilityLogic.js.map +1 -0
- package/lib/util/utils.d.ts +8 -0
- package/lib/util/utils.d.ts.map +1 -0
- package/lib/util/utils.js +48 -0
- package/lib/util/utils.js.map +1 -0
- package/package.json +15 -15
- package/src/acl/aclLogic.ts +137 -118
- package/src/authSession/authSession.ts +0 -0
- package/src/authn/SolidAuthnLogic.ts +3 -2
- package/src/authn/authUtil.ts +0 -0
- package/src/chat/chatLogic.ts +225 -0
- package/src/inbox/inboxLogic.ts +58 -0
- package/src/index.ts +11 -42
- package/src/issuer/issuerLogic.ts +1 -1
- package/src/logic/CustomError.ts +5 -1
- package/src/logic/solidLogic.ts +75 -0
- package/src/logic/solidLogicSingleton.ts +3 -3
- package/src/profile/profileLogic.ts +126 -0
- package/src/typeIndex/typeIndexLogic.ts +175 -182
- package/src/types.ts +83 -4
- package/src/util/containerLogic.ts +54 -0
- package/src/util/debug.ts +0 -0
- package/src/util/ns.ts +5 -0
- package/src/util/utilityLogic.ts +155 -0
- package/src/util/utils.ts +52 -0
- package/test/aclLogic.test.ts +13 -4
- package/test/authUtil.test.ts +0 -0
- package/test/chatLogic.test.ts +70 -71
- package/test/container.test.ts +56 -0
- package/test/helpers/dataSetup.ts +134 -0
- package/test/helpers/setup.ts +4 -0
- package/test/inboxLogic.test.ts +39 -38
- package/test/logic.test.ts +10 -9
- package/test/profileLogic.test.ts +246 -0
- package/test/solidAuthLogic.test.ts +0 -0
- package/test/typeIndexLogic.test.ts +487 -30
- package/test/utilityLogic.test.ts +172 -126
- package/test/utils.test.ts +32 -0
- package/tsconfig.json +0 -0
- package/lib/chat/ChatLogic.d.ts +0 -26
- package/lib/chat/ChatLogic.d.ts.map +0 -1
- package/lib/chat/ChatLogic.js.map +0 -1
- package/lib/chat/determineChatContainer.d.ts +0 -3
- package/lib/chat/determineChatContainer.d.ts.map +0 -1
- package/lib/chat/determineChatContainer.js +0 -12
- package/lib/chat/determineChatContainer.js.map +0 -1
- package/lib/discovery/discoveryLogic.d.ts +0 -37
- package/lib/discovery/discoveryLogic.d.ts.map +0 -1
- package/lib/discovery/discoveryLogic.js +0 -502
- package/lib/discovery/discoveryLogic.js.map +0 -1
- package/lib/inbox/InboxLogic.d.ts +0 -18
- package/lib/inbox/InboxLogic.d.ts.map +0 -1
- package/lib/inbox/InboxLogic.js.map +0 -1
- package/lib/logic/SolidLogic.d.ts +0 -45
- package/lib/logic/SolidLogic.d.ts.map +0 -1
- package/lib/logic/SolidLogic.js +0 -320
- package/lib/logic/SolidLogic.js.map +0 -1
- package/lib/profile/ProfileLogic.d.ts +0 -13
- package/lib/profile/ProfileLogic.d.ts.map +0 -1
- package/lib/profile/ProfileLogic.js.map +0 -1
- package/lib/util/UtilityLogic.d.ts +0 -27
- package/lib/util/UtilityLogic.d.ts.map +0 -1
- package/lib/util/UtilityLogic.js +0 -216
- package/lib/util/UtilityLogic.js.map +0 -1
- package/lib/util/uri.d.ts +0 -3
- package/lib/util/uri.d.ts.map +0 -1
- package/lib/util/uri.js +0 -9
- package/lib/util/uri.js.map +0 -1
- package/src/chat/ChatLogic.ts +0 -244
- package/src/chat/determineChatContainer.ts +0 -14
- package/src/discovery/discoveryLogic.ts +0 -269
- package/src/inbox/InboxLogic.ts +0 -66
- package/src/logic/SolidLogic.ts +0 -259
- package/src/profile/ProfileLogic.ts +0 -44
- package/src/util/UtilityLogic.ts +0 -144
- package/src/util/uri.ts +0 -5
- package/test/discoveryLogic.test.ts +0 -712
package/src/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Session } from "@inrupt/solid-client-authn-browser"
|
|
2
|
-
import { NamedNode } from "rdflib"
|
|
2
|
+
import { LiveStore, NamedNode, Statement } from "rdflib"
|
|
3
3
|
|
|
4
4
|
export type AppDetails = {
|
|
5
5
|
noun: string
|
|
@@ -32,12 +32,91 @@ export interface SolidNamespace {
|
|
|
32
32
|
[key: string]: (term: string) => NamedNode
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
export type TypeIndexScope = { label: string, index: NamedNode, agent: NamedNode }
|
|
36
|
+
export type ScopedApp = { instance: NamedNode, scope: TypeIndexScope }
|
|
37
|
+
|
|
38
|
+
export interface NewPaneOptions {
|
|
36
39
|
me?: NamedNode;
|
|
37
40
|
newInstance?: NamedNode;
|
|
38
41
|
newBase: string;
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
interface CreatedPaneOptions {
|
|
44
|
+
export interface CreatedPaneOptions {
|
|
42
45
|
newInstance: NamedNode;
|
|
43
|
-
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface ChatLogic {
|
|
49
|
+
setAcl: (chatContainer: NamedNode, me: NamedNode, invitee: NamedNode) => Promise<void>,
|
|
50
|
+
addToPrivateTypeIndex: (chatThing, me) => void | Promise<void>,
|
|
51
|
+
findChat: (invitee: NamedNode) => Promise<Chat>,
|
|
52
|
+
createChatThing: (chatContainer: NamedNode, me: NamedNode) => Promise<NamedNode>,
|
|
53
|
+
mintNew: (newPaneOptions: NewPaneOptions) => Promise<CreatedPaneOptions>,
|
|
54
|
+
getChat: (invitee: NamedNode, boolean) => Promise<NamedNode | null>,
|
|
55
|
+
sendInvite: (invitee: NamedNode, chatThing: NamedNode) => void
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface Chat {
|
|
59
|
+
me: NamedNode,
|
|
60
|
+
chatContainer: NamedNode,
|
|
61
|
+
exists: boolean
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface ProfileLogic {
|
|
65
|
+
silencedLoadPreferences: (user: NamedNode) => Promise<NamedNode | undefined>,
|
|
66
|
+
loadPreferences: (user: NamedNode) => Promise<NamedNode>,
|
|
67
|
+
loadProfile: (user: NamedNode) => Promise<NamedNode>,
|
|
68
|
+
loadMe: () => Promise<NamedNode>,
|
|
69
|
+
getPodRoot: (user: NamedNode) => NamedNode,
|
|
70
|
+
getMainInbox: (user: NamedNode) => Promise<NamedNode>,
|
|
71
|
+
findStorage: (me: NamedNode) => Node | null
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface AclLogic {
|
|
75
|
+
findAclDocUrl: (url: string) => Promise<any>,
|
|
76
|
+
setACLUserPublic: (docURI: string, me: NamedNode,
|
|
77
|
+
options: {
|
|
78
|
+
defaultForNew?: boolean,
|
|
79
|
+
public?: []
|
|
80
|
+
}
|
|
81
|
+
) => Promise<NamedNode>,
|
|
82
|
+
genACLText: (docURI: string, me: NamedNode, aclURI: string,
|
|
83
|
+
options: {
|
|
84
|
+
defaultForNew?: boolean,
|
|
85
|
+
public?: []
|
|
86
|
+
}
|
|
87
|
+
) => string | undefined
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface InboxLogic {
|
|
91
|
+
createInboxFor: (peerWebId: string, nick: string) => Promise<string>,
|
|
92
|
+
getNewMessages: (user?: NamedNode) => Promise<string[]>,
|
|
93
|
+
markAsRead: (url: string, date: Date) => void
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface TypeIndexLogic {
|
|
97
|
+
getRegistrations: (instance, theClass) => Node[],
|
|
98
|
+
loadTypeIndexesFor: (user: NamedNode) => Promise<Array<TypeIndexScope>>,
|
|
99
|
+
loadCommunityTypeIndexes: (user: NamedNode) => Promise<TypeIndexScope[][]>,
|
|
100
|
+
loadAllTypeIndexes: (user: NamedNode) => Promise<Array<TypeIndexScope>>,
|
|
101
|
+
getScopedAppInstances: (klass: NamedNode, user: NamedNode) => Promise<ScopedApp[]>,
|
|
102
|
+
getAppInstances: (klass: NamedNode) => Promise<NamedNode[]>,
|
|
103
|
+
suggestPublicTypeIndex: (me: NamedNode) => NamedNode,
|
|
104
|
+
suggestPrivateTypeIndex: (preferencesFile: NamedNode) => NamedNode,
|
|
105
|
+
registerInTypeIndex: (instance: NamedNode, index: NamedNode, theClass: NamedNode) => Promise<NamedNode | null>,
|
|
106
|
+
deleteTypeIndexRegistration: (item: any) => Promise<void>
|
|
107
|
+
getScopedAppsFromIndex: (scope: TypeIndexScope, theClass: NamedNode | null) => Promise<ScopedApp[]>
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface SolidLogic {
|
|
111
|
+
store: LiveStore,
|
|
112
|
+
authn: AuthnLogic,
|
|
113
|
+
acl: AclLogic,
|
|
114
|
+
profile: ProfileLogic,
|
|
115
|
+
inbox: InboxLogic,
|
|
116
|
+
typeIndex: TypeIndexLogic,
|
|
117
|
+
chat: ChatLogic,
|
|
118
|
+
load: (doc: NamedNode | NamedNode[] | string) => void,
|
|
119
|
+
updatePromise: (del: Array<Statement>, ins: Array<Statement>) => Promise<void>,
|
|
120
|
+
clearStore: () => void
|
|
121
|
+
}
|
|
122
|
+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { NamedNode, Statement, sym } from "rdflib";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Container-related class
|
|
5
|
+
*/
|
|
6
|
+
export function createContainerLogic(store) {
|
|
7
|
+
|
|
8
|
+
function getContainerElements(containerNode: NamedNode): NamedNode[] {
|
|
9
|
+
return store
|
|
10
|
+
.statementsMatching(
|
|
11
|
+
containerNode,
|
|
12
|
+
sym("http://www.w3.org/ns/ldp#contains"),
|
|
13
|
+
undefined,
|
|
14
|
+
containerNode.doc()
|
|
15
|
+
)
|
|
16
|
+
.map((st: Statement) => st.object as NamedNode);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isContainer(url: string) {
|
|
20
|
+
return url.charAt(url.length - 1) === "/";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function createContainer(url: string) {
|
|
24
|
+
if (!isContainer(url)) {
|
|
25
|
+
throw new Error(`Not a container URL ${url}`);
|
|
26
|
+
}
|
|
27
|
+
// Copied from https://github.com/solidos/solid-crud-tests/blob/v3.1.0/test/surface/create-container.test.ts#L56-L64
|
|
28
|
+
const result = await store.fetcher._fetch(url, {
|
|
29
|
+
method: "PUT",
|
|
30
|
+
headers: {
|
|
31
|
+
"Content-Type": "text/turtle",
|
|
32
|
+
"If-None-Match": "*",
|
|
33
|
+
Link: '<http://www.w3.org/ns/ldp#BasicContainer>; rel="type"', // See https://github.com/solidos/node-solid-server/issues/1465
|
|
34
|
+
},
|
|
35
|
+
body: " ", // work around https://github.com/michielbdejong/community-server/issues/4#issuecomment-776222863
|
|
36
|
+
});
|
|
37
|
+
if (result.status.toString()[0] !== '2') {
|
|
38
|
+
throw new Error(`Not OK: got ${result.status} response while creating container at ${url}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function getContainerMembers(containerUrl: string): Promise<string[]> {
|
|
43
|
+
const containerNode = store.sym(containerUrl);
|
|
44
|
+
await store.fetcher.load(containerNode);
|
|
45
|
+
const nodes = getContainerElements(containerNode);
|
|
46
|
+
return nodes.map(node => node.value);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
isContainer,
|
|
50
|
+
createContainer,
|
|
51
|
+
getContainerElements,
|
|
52
|
+
getContainerMembers
|
|
53
|
+
}
|
|
54
|
+
}
|
package/src/util/debug.ts
CHANGED
|
File without changes
|
package/src/util/ns.ts
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { NamedNode, st } from "rdflib";
|
|
2
|
+
import { CrossOriginForbiddenError, FetchError, NotEditableError, SameOriginForbiddenError, UnauthorizedError, WebOperationError } from "../logic/CustomError";
|
|
3
|
+
import * as debug from '../util/debug';
|
|
4
|
+
import { differentOrigin } from "./utils";
|
|
5
|
+
|
|
6
|
+
export function createUtilityLogic(store, aclLogic, containerLogic) {
|
|
7
|
+
|
|
8
|
+
async function recursiveDelete(url: string) {
|
|
9
|
+
try {
|
|
10
|
+
if (containerLogic.isContainer(url)) {
|
|
11
|
+
const aclDocUrl = await aclLogic.findAclDocUrl(url);
|
|
12
|
+
await store.fetcher._fetch(aclDocUrl, { method: "DELETE" });
|
|
13
|
+
const containerMembers = await containerLogic.getContainerMembers(url);
|
|
14
|
+
await Promise.all(
|
|
15
|
+
containerMembers.map((url) => recursiveDelete(url))
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
return store.fetcher._fetch(url, { method: "DELETE" });
|
|
19
|
+
} catch (e) {
|
|
20
|
+
// debug.log(`Please manually remove ${url} from your system under test.`, e);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Create a resource if it really does not exist
|
|
26
|
+
* Be absolutely sure something does not exist before creating a new empty file
|
|
27
|
+
* as otherwise existing could be deleted.
|
|
28
|
+
* @param doc {NamedNode} - The resource
|
|
29
|
+
*/
|
|
30
|
+
async function loadOrCreateIfNotExists(doc: NamedNode) {
|
|
31
|
+
let response
|
|
32
|
+
try {
|
|
33
|
+
response = await store.fetcher.load(doc)
|
|
34
|
+
} catch (err) {
|
|
35
|
+
if (err.response.status === 404) {
|
|
36
|
+
try {
|
|
37
|
+
await store.fetcher.webOperation('PUT', doc, { data: '', contentType: 'text/turtle' })
|
|
38
|
+
} catch (err) {
|
|
39
|
+
const msg = 'createIfNotExists: PUT FAILED: ' + doc + ': ' + err
|
|
40
|
+
throw new WebOperationError(msg)
|
|
41
|
+
}
|
|
42
|
+
await store.fetcher.load(doc)
|
|
43
|
+
} else {
|
|
44
|
+
if (err.response.status === 401) {
|
|
45
|
+
throw new UnauthorizedError();
|
|
46
|
+
}
|
|
47
|
+
if (err.response.status === 403) {
|
|
48
|
+
if (differentOrigin(doc)) {
|
|
49
|
+
throw new CrossOriginForbiddenError();
|
|
50
|
+
}
|
|
51
|
+
throw new SameOriginForbiddenError();
|
|
52
|
+
}
|
|
53
|
+
const msg = 'createIfNotExists doc load error NOT 404: ' + doc + ': ' + err
|
|
54
|
+
throw new FetchError(err.status, err.message + msg)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return response
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Follow link from this doc to another thing, or else make a new link
|
|
61
|
+
**
|
|
62
|
+
** @returns existing object, or creates it if non existent
|
|
63
|
+
*/
|
|
64
|
+
async function followOrCreateLink(subject: NamedNode, predicate: NamedNode,
|
|
65
|
+
object: NamedNode, doc: NamedNode
|
|
66
|
+
): Promise<NamedNode | null> {
|
|
67
|
+
await store.fetcher.load(doc)
|
|
68
|
+
const result = store.any(subject, predicate, null, doc)
|
|
69
|
+
|
|
70
|
+
if (result) return result as NamedNode
|
|
71
|
+
if (!store.updater.editable(doc)) {
|
|
72
|
+
const msg = `followOrCreateLink: cannot edit ${doc.value}`
|
|
73
|
+
debug.warn(msg)
|
|
74
|
+
throw new NotEditableError(msg)
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
await store.updater.update([], [st(subject, predicate, object, doc)])
|
|
78
|
+
} catch (err) {
|
|
79
|
+
const msg = `followOrCreateLink: Error making link in ${doc} to ${object}: ${err}`
|
|
80
|
+
debug.warn(msg)
|
|
81
|
+
throw new WebOperationError(err)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
await loadOrCreateIfNotExists(object)
|
|
86
|
+
// store.fetcher.webOperation('PUT', object, { data: '', contentType: 'text/turtle'})
|
|
87
|
+
} catch (err) {
|
|
88
|
+
debug.warn(`followOrCreateLink: Error loading or saving new linked document: ${object}: ${err}`)
|
|
89
|
+
throw err;
|
|
90
|
+
}
|
|
91
|
+
return object
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Copied from https://github.com/solidos/web-access-control-tests/blob/v3.0.0/test/surface/delete.test.ts#L5
|
|
95
|
+
async function setSinglePeerAccess(options: {
|
|
96
|
+
ownerWebId: string,
|
|
97
|
+
peerWebId: string,
|
|
98
|
+
accessToModes?: string,
|
|
99
|
+
defaultModes?: string,
|
|
100
|
+
target: string
|
|
101
|
+
}) {
|
|
102
|
+
let str = [
|
|
103
|
+
'@prefix acl: <http://www.w3.org/ns/auth/acl#>.',
|
|
104
|
+
'',
|
|
105
|
+
`<#alice> a acl:Authorization;\n acl:agent <${options.ownerWebId}>;`,
|
|
106
|
+
` acl:accessTo <${options.target}>;`,
|
|
107
|
+
` acl:default <${options.target}>;`,
|
|
108
|
+
' acl:mode acl:Read, acl:Write, acl:Control.',
|
|
109
|
+
''
|
|
110
|
+
].join('\n')
|
|
111
|
+
if (options.accessToModes) {
|
|
112
|
+
str += [
|
|
113
|
+
'<#bobAccessTo> a acl:Authorization;',
|
|
114
|
+
` acl:agent <${options.peerWebId}>;`,
|
|
115
|
+
` acl:accessTo <${options.target}>;`,
|
|
116
|
+
` acl:mode ${options.accessToModes}.`,
|
|
117
|
+
''
|
|
118
|
+
].join('\n')
|
|
119
|
+
}
|
|
120
|
+
if (options.defaultModes) {
|
|
121
|
+
str += [
|
|
122
|
+
'<#bobDefault> a acl:Authorization;',
|
|
123
|
+
` acl:agent <${options.peerWebId}>;`,
|
|
124
|
+
` acl:default <${options.target}>;`,
|
|
125
|
+
` acl:mode ${options.defaultModes}.`,
|
|
126
|
+
''
|
|
127
|
+
].join('\n')
|
|
128
|
+
}
|
|
129
|
+
const aclDocUrl = await aclLogic.findAclDocUrl(options.target);
|
|
130
|
+
return store.fetcher._fetch(aclDocUrl, {
|
|
131
|
+
method: 'PUT',
|
|
132
|
+
body: str,
|
|
133
|
+
headers: [
|
|
134
|
+
['Content-Type', 'text/turtle']
|
|
135
|
+
]
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function createEmptyRdfDoc(doc: NamedNode, comment: string) {
|
|
140
|
+
await store.fetcher.webOperation("PUT", doc.uri, {
|
|
141
|
+
data: `# ${new Date()} ${comment}
|
|
142
|
+
`,
|
|
143
|
+
contentType: "text/turtle",
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
recursiveDelete,
|
|
149
|
+
setSinglePeerAccess,
|
|
150
|
+
createEmptyRdfDoc,
|
|
151
|
+
followOrCreateLink,
|
|
152
|
+
loadOrCreateIfNotExists
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { NamedNode, sym } from "rdflib";
|
|
2
|
+
|
|
3
|
+
export function newThing(doc: NamedNode): NamedNode {
|
|
4
|
+
return sym(doc.uri + "#" + "id" + ("" + Date.now()));
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function uniqueNodes (arr: NamedNode[]): NamedNode[] {
|
|
8
|
+
const uris = arr.map(x => x.uri)
|
|
9
|
+
const set = new Set(uris)
|
|
10
|
+
const uris2 = Array.from(set)
|
|
11
|
+
const arr2 = uris2.map(u => new NamedNode(u))
|
|
12
|
+
return arr2 // Array.from(new Set(arr.map(x => x.uri))).map(u => sym(u))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getArchiveUrl(baseUrl: string, date: Date) {
|
|
16
|
+
const year = date.getUTCFullYear();
|
|
17
|
+
const month = ('0' + (date.getUTCMonth()+1)).slice(-2);
|
|
18
|
+
const day = ('0' + (date.getUTCDate())).slice(-2);
|
|
19
|
+
const parts = baseUrl.split('/');
|
|
20
|
+
const filename = parts[parts.length -1 ];
|
|
21
|
+
return new URL(`./archive/${year}/${month}/${day}/${filename}`, baseUrl).toString();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function differentOrigin(doc): boolean {
|
|
25
|
+
if (!doc) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
return (
|
|
29
|
+
`${window.location.origin}/` !== new URL(doc.value).origin
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function suggestPreferencesFile (me:NamedNode) {
|
|
34
|
+
const stripped = me.uri.replace('/profile/', '/').replace('/public/', '/')
|
|
35
|
+
// const stripped = me.uri.replace(\/[p|P]rofile/\g, '/').replace(\/[p|P]ublic/\g, '/')
|
|
36
|
+
const folderURI = stripped.split('/').slice(0,-1).join('/') + '/Settings/'
|
|
37
|
+
const fileURI = folderURI + 'Preferences.ttl'
|
|
38
|
+
return sym(fileURI)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function determineChatContainer(
|
|
42
|
+
invitee: NamedNode,
|
|
43
|
+
podRoot: NamedNode
|
|
44
|
+
): NamedNode {
|
|
45
|
+
// Create chat
|
|
46
|
+
// See https://gitter.im/solid/chat-app?at=5f3c800f855be416a23ae74a
|
|
47
|
+
const chatContainerStr = new URL(
|
|
48
|
+
`IndividualChats/${new URL(invitee.value).host}/`,
|
|
49
|
+
podRoot.value
|
|
50
|
+
).toString();
|
|
51
|
+
return new NamedNode(chatContainerStr);
|
|
52
|
+
}
|
package/test/aclLogic.test.ts
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
import { sym } from 'rdflib'
|
|
2
|
-
import {
|
|
1
|
+
import { Fetcher, Store, sym, UpdateManager } from 'rdflib';
|
|
2
|
+
import { createAclLogic } from '../src/acl/aclLogic';
|
|
3
3
|
|
|
4
4
|
describe('setACLUserPublic', () => {
|
|
5
|
+
let aclLogic
|
|
6
|
+
let store
|
|
7
|
+
beforeAll(() => {
|
|
8
|
+
const options = { fetch: fetch };
|
|
9
|
+
store = new Store()
|
|
10
|
+
store.fetcher = new Fetcher(store, options);
|
|
11
|
+
store.updater = new UpdateManager(store);
|
|
12
|
+
aclLogic = createAclLogic(store)
|
|
13
|
+
})
|
|
5
14
|
it('exists', () => {
|
|
6
|
-
expect(setACLUserPublic).toBeInstanceOf(Function)
|
|
15
|
+
expect(aclLogic.setACLUserPublic).toBeInstanceOf(Function)
|
|
7
16
|
})
|
|
8
17
|
it.skip('runs', async () => {
|
|
9
|
-
expect(await setACLUserPublic(
|
|
18
|
+
expect(await aclLogic.setACLUserPublic(
|
|
10
19
|
'https://test.test#',
|
|
11
20
|
sym('https://test.test#'),
|
|
12
21
|
{}
|
package/test/authUtil.test.ts
CHANGED
|
File without changes
|