solid-logic 1.3.12-bbf45639 → 1.3.13-438dc3ae

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.
Files changed (135) hide show
  1. package/.babelrc +0 -0
  2. package/.eslintrc.js +0 -0
  3. package/.github/workflows/ci.yml +40 -5
  4. package/.github/workflows/release.yml +0 -0
  5. package/LICENSE +0 -0
  6. package/README.md +0 -0
  7. package/jest.config.js +4 -1
  8. package/lib/acl/aclLogic.d.ts +32 -0
  9. package/lib/acl/aclLogic.d.ts.map +1 -0
  10. package/lib/acl/aclLogic.js +132 -0
  11. package/lib/acl/aclLogic.js.map +1 -0
  12. package/lib/authSession/authSession.d.ts +4 -0
  13. package/lib/authSession/authSession.d.ts.map +1 -0
  14. package/lib/authSession/authSession.js +18 -0
  15. package/lib/authSession/authSession.js.map +1 -0
  16. package/lib/authn/SolidAuthnLogic.d.ts +26 -6
  17. package/lib/authn/SolidAuthnLogic.d.ts.map +1 -1
  18. package/lib/authn/SolidAuthnLogic.js +161 -5
  19. package/lib/authn/SolidAuthnLogic.js.map +1 -1
  20. package/lib/authn/authUtil.d.ts +17 -0
  21. package/lib/authn/authUtil.d.ts.map +1 -0
  22. package/lib/authn/authUtil.js +88 -0
  23. package/lib/authn/authUtil.js.map +1 -0
  24. package/lib/chat/ChatLogic.d.ts +2 -2
  25. package/lib/chat/ChatLogic.d.ts.map +1 -1
  26. package/lib/chat/ChatLogic.js +1 -1
  27. package/lib/chat/ChatLogic.js.map +1 -1
  28. package/lib/chat/determineChatContainer.d.ts +0 -0
  29. package/lib/chat/determineChatContainer.d.ts.map +0 -0
  30. package/lib/chat/determineChatContainer.js +0 -0
  31. package/lib/chat/determineChatContainer.js.map +0 -0
  32. package/lib/inbox/InboxLogic.d.ts +2 -2
  33. package/lib/inbox/InboxLogic.d.ts.map +1 -1
  34. package/lib/inbox/InboxLogic.js +0 -0
  35. package/lib/inbox/InboxLogic.js.map +1 -1
  36. package/lib/index.d.ts +9 -67
  37. package/lib/index.d.ts.map +1 -1
  38. package/lib/index.js +31 -384
  39. package/lib/index.js.map +1 -1
  40. package/lib/issuer/issuerLogic.d.ts +8 -0
  41. package/lib/issuer/issuerLogic.d.ts.map +1 -0
  42. package/lib/issuer/issuerLogic.js +53 -0
  43. package/lib/issuer/issuerLogic.js.map +1 -0
  44. package/lib/logic/CustomError.d.ts +17 -0
  45. package/lib/logic/CustomError.d.ts.map +1 -0
  46. package/lib/logic/CustomError.js +73 -0
  47. package/lib/logic/CustomError.js.map +1 -0
  48. package/lib/logic/SolidLogic.d.ts +49 -0
  49. package/lib/logic/SolidLogic.d.ts.map +1 -0
  50. package/lib/logic/SolidLogic.js +316 -0
  51. package/lib/logic/SolidLogic.js.map +1 -0
  52. package/lib/logic/solidLogicSingleton.d.ts +8 -0
  53. package/lib/logic/solidLogicSingleton.d.ts.map +1 -0
  54. package/lib/logic/solidLogicSingleton.js +88 -0
  55. package/lib/logic/solidLogicSingleton.js.map +1 -0
  56. package/lib/profile/ProfileLogic.d.ts +2 -3
  57. package/lib/profile/ProfileLogic.d.ts.map +1 -1
  58. package/lib/profile/ProfileLogic.js +0 -0
  59. package/lib/profile/ProfileLogic.js.map +1 -1
  60. package/lib/typeIndex/typeIndexLogic.d.ts +22 -0
  61. package/lib/typeIndex/typeIndexLogic.d.ts.map +1 -0
  62. package/lib/typeIndex/typeIndexLogic.js +302 -0
  63. package/lib/typeIndex/typeIndexLogic.js.map +1 -0
  64. package/lib/types.d.ts +29 -0
  65. package/lib/types.d.ts.map +1 -0
  66. package/lib/{authn/index.js → types.js} +1 -1
  67. package/lib/types.js.map +1 -0
  68. package/lib/util/UtilityLogic.d.ts +2 -2
  69. package/lib/util/UtilityLogic.d.ts.map +1 -1
  70. package/lib/util/UtilityLogic.js +0 -0
  71. package/lib/util/UtilityLogic.js.map +1 -1
  72. package/lib/{debug.d.ts → util/debug.d.ts} +0 -0
  73. package/lib/util/debug.d.ts.map +1 -0
  74. package/lib/{debug.js → util/debug.js} +0 -0
  75. package/lib/util/debug.js.map +1 -0
  76. package/lib/{uri.d.ts → util/uri.d.ts} +0 -0
  77. package/lib/util/uri.d.ts.map +1 -0
  78. package/lib/{uri.js → util/uri.js} +0 -0
  79. package/lib/util/uri.js.map +1 -0
  80. package/package.json +5 -3
  81. package/renovate.json +0 -0
  82. package/src/acl/aclLogic.ts +137 -0
  83. package/src/authSession/authSession.ts +22 -0
  84. package/src/authn/SolidAuthnLogic.ts +112 -10
  85. package/src/authn/authUtil.ts +67 -0
  86. package/src/chat/ChatLogic.ts +3 -3
  87. package/src/chat/determineChatContainer.ts +0 -0
  88. package/src/inbox/InboxLogic.ts +2 -14
  89. package/src/index.ts +18 -308
  90. package/src/issuer/issuerLogic.ts +40 -0
  91. package/src/logic/CustomError.ts +25 -0
  92. package/src/logic/SolidLogic.ts +264 -0
  93. package/src/logic/solidLogicSingleton.ts +24 -0
  94. package/src/profile/ProfileLogic.ts +2 -3
  95. package/src/typeIndex/typeIndexLogic.ts +170 -0
  96. package/src/types.ts +41 -0
  97. package/src/util/UtilityLogic.ts +2 -14
  98. package/src/{debug.ts → util/debug.ts} +0 -0
  99. package/src/{uri.ts → util/uri.ts} +0 -0
  100. package/test/aclLogic.test.ts +15 -0
  101. package/test/authUtil.test.ts +19 -0
  102. package/{src/chat/integration.test.ts → test/chatLogic.test.ts} +4 -5
  103. package/test/helpers/setup.ts +13 -0
  104. package/{src/inbox/unit.test.ts → test/inboxLogic.test.ts} +5 -6
  105. package/test/logic.test.ts +28 -0
  106. package/test/solidAuthLogic.test.ts +45 -0
  107. package/test/typeIndexLogic.test.ts +26 -0
  108. package/{src/util/unit.test.ts → test/utilityLogic.test.ts} +3 -4
  109. package/tsconfig.json +0 -0
  110. package/jest.setup.ts +0 -2
  111. package/lib/authn/NoAuthnLogic.d.ts +0 -9
  112. package/lib/authn/NoAuthnLogic.d.ts.map +0 -1
  113. package/lib/authn/NoAuthnLogic.js +0 -17
  114. package/lib/authn/NoAuthnLogic.js.map +0 -1
  115. package/lib/authn/index.d.ts +0 -5
  116. package/lib/authn/index.d.ts.map +0 -1
  117. package/lib/authn/index.js.map +0 -1
  118. package/lib/chat/integration.test.d.ts +0 -2
  119. package/lib/chat/integration.test.d.ts.map +0 -1
  120. package/lib/chat/integration.test.js +0 -318
  121. package/lib/chat/integration.test.js.map +0 -1
  122. package/lib/debug.d.ts.map +0 -1
  123. package/lib/debug.js.map +0 -1
  124. package/lib/inbox/unit.test.d.ts +0 -2
  125. package/lib/inbox/unit.test.d.ts.map +0 -1
  126. package/lib/inbox/unit.test.js +0 -264
  127. package/lib/inbox/unit.test.js.map +0 -1
  128. package/lib/uri.d.ts.map +0 -1
  129. package/lib/uri.js.map +0 -1
  130. package/lib/util/unit.test.d.ts +0 -2
  131. package/lib/util/unit.test.d.ts.map +0 -1
  132. package/lib/util/unit.test.js +0 -200
  133. package/lib/util/unit.test.js.map +0 -1
  134. package/src/authn/NoAuthnLogic.ts +0 -16
  135. package/src/authn/index.ts +0 -5
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Simple Access Control
3
+ *
4
+ * This function sets up a simple default ACL for a resource, with
5
+ * RWC for the owner, and a specified access (default none) for the public.
6
+ * In all cases owner has read write control.
7
+ * Parameter lists modes allowed to public
8
+ *
9
+ * @param options
10
+ * @param options.public eg ['Read', 'Write']
11
+ *
12
+ * @returns Resolves with aclDoc uri on successful write
13
+ */
14
+
15
+ import { graph, NamedNode, Namespace, serialize } from "rdflib"
16
+ import solidNamespace from 'solid-namespace'
17
+ import * as $rdf from 'rdflib'
18
+ import { solidLogicSingleton } from "../logic/solidLogicSingleton"
19
+ import { ACL_LINK } from "../util/UtilityLogic"
20
+
21
+ export const ns = solidNamespace($rdf)
22
+
23
+ export function setACLUserPublic (
24
+ docURI: string,
25
+ me: NamedNode,
26
+ options: {
27
+ defaultForNew?: boolean,
28
+ public?: []
29
+ }
30
+ ): Promise<NamedNode> {
31
+ const aclDoc = solidLogicSingleton.store.any(
32
+ solidLogicSingleton.store.sym(docURI),
33
+ ACL_LINK
34
+ )
35
+
36
+ return Promise.resolve()
37
+ .then(() => {
38
+ if (aclDoc) {
39
+ return aclDoc as NamedNode
40
+ }
41
+
42
+ return fetchACLRel(docURI).catch(err => {
43
+ throw new Error(`Error fetching rel=ACL header for ${docURI}: ${err}`)
44
+ })
45
+ })
46
+ .then(aclDoc => {
47
+ const aclText = genACLText(docURI, me, aclDoc.uri, options)
48
+ if (!solidLogicSingleton.store.fetcher) {
49
+ throw new Error('Cannot PUT this, store has no fetcher')
50
+ }
51
+ return solidLogicSingleton.store.fetcher
52
+ .webOperation('PUT', aclDoc.uri, {
53
+ data: aclText,
54
+ contentType: 'text/turtle'
55
+ })
56
+ .then(result => {
57
+ if (!result.ok) {
58
+ throw new Error('Error writing ACL text: ' + result.error)
59
+ }
60
+
61
+ return aclDoc
62
+ })
63
+ })
64
+ }
65
+
66
+ /**
67
+ * @param docURI
68
+ * @returns
69
+ */
70
+ function fetchACLRel (docURI: string): Promise<NamedNode> {
71
+ const fetcher = solidLogicSingleton.store.fetcher
72
+ if (!fetcher) {
73
+ throw new Error('Cannot fetch ACL rel, store has no fetcher')
74
+ }
75
+
76
+ return fetcher.load(docURI).then(result => {
77
+ if (!result.ok) {
78
+ throw new Error('fetchACLRel: While loading:' + (result as any).error)
79
+ }
80
+
81
+ const aclDoc = solidLogicSingleton.store.any(
82
+ solidLogicSingleton.store.sym(docURI),
83
+ ACL_LINK
84
+ )
85
+
86
+ if (!aclDoc) {
87
+ throw new Error('fetchACLRel: No Link rel=ACL header for ' + docURI)
88
+ }
89
+
90
+ return aclDoc as NamedNode
91
+ })
92
+ }
93
+
94
+ /**
95
+ * @param docURI
96
+ * @param me
97
+ * @param aclURI
98
+ * @param options
99
+ *
100
+ * @returns Serialized ACL
101
+ */
102
+ export function genACLText (
103
+ docURI: string,
104
+ me: NamedNode,
105
+ aclURI: string,
106
+ options: {
107
+ defaultForNew?: boolean,
108
+ public?: []
109
+ } = {}
110
+ ): string | undefined {
111
+ const optPublic = options.public || []
112
+ const g = graph()
113
+ const auth = Namespace('http://www.w3.org/ns/auth/acl#')
114
+ let a = g.sym(`${aclURI}#a1`)
115
+ const acl = g.sym(aclURI)
116
+ const doc = g.sym(docURI)
117
+ g.add(a, ns.rdf('type'), auth('Authorization'), acl)
118
+ g.add(a, auth('accessTo'), doc, acl)
119
+ if (options.defaultForNew) {
120
+ g.add(a, auth('default'), doc, acl)
121
+ }
122
+ g.add(a, auth('agent'), me, acl)
123
+ g.add(a, auth('mode'), auth('Read'), acl)
124
+ g.add(a, auth('mode'), auth('Write'), acl)
125
+ g.add(a, auth('mode'), auth('Control'), acl)
126
+
127
+ if (optPublic.length) {
128
+ a = g.sym(`${aclURI}#a2`)
129
+ g.add(a, ns.rdf('type'), auth('Authorization'), acl)
130
+ g.add(a, auth('accessTo'), doc, acl)
131
+ g.add(a, auth('agentClass'), ns.foaf('Agent'), acl)
132
+ for (let p = 0; p < optPublic.length; p++) {
133
+ g.add(a, auth('mode'), auth(optPublic[p]), acl) // Like 'Read' etc
134
+ }
135
+ }
136
+ return serialize(acl, g, aclURI)
137
+ }
@@ -0,0 +1,22 @@
1
+ import {
2
+ Session,
3
+ getClientAuthenticationWithDependencies
4
+ } from '@inrupt/solid-client-authn-browser'
5
+
6
+ let authSession: Session
7
+ // @ts-ignore
8
+ if (!window.authSession) {
9
+ authSession = new Session(
10
+ {
11
+ clientAuthentication: getClientAuthenticationWithDependencies({})
12
+ },
13
+ 'mySession'
14
+ )
15
+ // @ts-ignore
16
+ window.authSession = authSession
17
+ } else {
18
+ // @ts-ignore
19
+ authSession = window.authSession
20
+ }
21
+
22
+ export default authSession
@@ -1,18 +1,120 @@
1
- import { NamedNode, sym } from "rdflib";
2
- import { AuthnLogic } from "./index";
1
+ import { namedNode, NamedNode, sym } from "rdflib";
2
+ import { appContext, offlineTestID } from "./authUtil";
3
+ import * as debug from '../util/debug'
3
4
  import { Session } from "@inrupt/solid-client-authn-browser";
4
-
5
- /**
6
- * Implements AuthnLogic relying on solid-auth-client
7
- */
8
- export class SolidAuthnLogic implements AuthnLogic {
9
- private session?: Session;
5
+ import { AuthenticationContext } from "../types";
6
+ export class SolidAuthnLogic {
7
+ private session: Session;
10
8
 
11
9
  constructor(solidAuthSession: Session) {
12
10
  this.session = solidAuthSession;
13
11
  }
14
12
 
15
13
  currentUser(): NamedNode | null {
16
- return this.session?.info.webId ? sym(this.session.info.webId) : null;
14
+ const app = appContext()
15
+ if (app.viewingNoAuthPage) {
16
+ return sym(app.webId)
17
+ }
18
+ if (this.session.info.webId && this.session.info.isLoggedIn) {
19
+ return sym(this.session.info.webId)
20
+ }
21
+ return offlineTestID() // null unless testing
22
+ }
23
+
24
+ /**
25
+ * Retrieves currently logged in webId from either
26
+ * defaultTestUser or SolidAuth
27
+ * Also activates a session after login
28
+ * @param [setUserCallback] Optional callback
29
+ * @returns Resolves with webId uri, if no callback provided
30
+ */
31
+ async checkUser<T> (
32
+ setUserCallback?: (me: NamedNode | null) => T
33
+ ): Promise<NamedNode | T | null> {
34
+ // Save hash for "restorePreviousSession"
35
+ const preLoginRedirectHash = new URL(window.location.href).hash
36
+ if (preLoginRedirectHash) {
37
+ window.localStorage.setItem('preLoginRedirectHash', preLoginRedirectHash)
38
+ }
39
+ this.session.onSessionRestore((url) => {
40
+ if (document.location.toString() !== url) history.replaceState(null, '', url)
41
+ })
42
+
43
+ /**
44
+ * Handle a successful authentication redirect
45
+ */
46
+ await this.session
47
+ .handleIncomingRedirect({
48
+ restorePreviousSession: true,
49
+ url: window.location.href
50
+ })
51
+
52
+ // Check to see if a hash was stored in local storage
53
+ const postLoginRedirectHash = window.localStorage.getItem('preLoginRedirectHash')
54
+ if (postLoginRedirectHash) {
55
+ const curUrl = new URL(window.location.href)
56
+ if (curUrl.hash !== postLoginRedirectHash) {
57
+ if (history.pushState) {
58
+ // console.log('Setting window.location.has using pushState')
59
+ history.pushState(null, document.title, postLoginRedirectHash)
60
+ } else {
61
+ // console.warn('Setting window.location.has using location.hash')
62
+ location.hash = postLoginRedirectHash
63
+ }
64
+ curUrl.hash = postLoginRedirectHash
65
+ }
66
+ // See https://stackoverflow.com/questions/3870057/how-can-i-update-window-location-hash-without-jumping-the-document
67
+ // window.location.href = curUrl.toString()// @@ See https://developer.mozilla.org/en-US/docs/Web/API/Window/location
68
+ window.localStorage.setItem('preLoginRedirectHash', '')
69
+ }
70
+
71
+ // Check to see if already logged in / have the WebID
72
+ let me = offlineTestID()
73
+ if (me) {
74
+ return Promise.resolve(setUserCallback ? setUserCallback(me) : me)
75
+ }
76
+
77
+ const webId = this.webIdFromSession(this.session.info)
78
+ if (webId) {
79
+ me = this.saveUser(webId)
80
+ }
81
+
82
+ if (me) {
83
+ debug.log(`(Logged in as ${me} by authentication)`)
84
+ }
85
+
86
+ return Promise.resolve(setUserCallback ? setUserCallback(me) : me)
87
+ }
88
+
89
+ /**
90
+ * Saves `webId` in `context.me`
91
+ * @param webId
92
+ * @param context
93
+ *
94
+ * @returns Returns the WebID, after setting it
95
+ */
96
+ saveUser (
97
+ webId: NamedNode | string | null,
98
+ context?: AuthenticationContext
99
+ ): NamedNode | null {
100
+ let webIdUri: string
101
+ if (webId) {
102
+ webIdUri = (typeof webId === 'string') ? webId : webId.uri
103
+ const me = namedNode(webIdUri)
104
+ if (context) {
105
+ context.me = me
106
+ }
107
+ return me
108
+ }
109
+ return null
17
110
  }
18
- }
111
+
112
+ /**
113
+ * @returns {Promise<string|null>} Resolves with WebID URI or null
114
+ */
115
+ webIdFromSession (session?: { webId?: string, isLoggedIn: boolean }): string | null {
116
+ const webId = session?.webId && session.isLoggedIn ? session.webId : null
117
+ return webId
118
+ }
119
+
120
+ }
@@ -0,0 +1,67 @@
1
+ import { NamedNode, sym } from "rdflib"
2
+ import * as debug from '../util/debug'
3
+
4
+ /**
5
+ * find a user or app's context as set in window.SolidAppContext
6
+ * this is a const, not a function, because we have problems to jest mock it otherwise
7
+ * see: https://github.com/facebook/jest/issues/936#issuecomment-545080082 for more
8
+ * @return {any} - an appContext object
9
+ */
10
+ export const appContext = ():any => {
11
+ let { SolidAppContext }: any = window
12
+ SolidAppContext ||= {}
13
+ SolidAppContext.viewingNoAuthPage = false
14
+ if (SolidAppContext.noAuth && window.document) {
15
+ const currentPage = window.document.location.href
16
+ if (currentPage.startsWith(SolidAppContext.noAuth)) {
17
+ SolidAppContext.viewingNoAuthPage = true
18
+ const params = new URLSearchParams(window.document.location.search)
19
+ if (params) {
20
+ let viewedPage = SolidAppContext.viewedPage = params.get('uri') || null
21
+ if (viewedPage) {
22
+ viewedPage = decodeURI(viewedPage)
23
+ if (!viewedPage.startsWith(SolidAppContext.noAuth)) {
24
+ const ary = viewedPage.split(/\//)
25
+ SolidAppContext.idp = ary[0] + '//' + ary[2]
26
+ SolidAppContext.viewingNoAuthPage = false
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
32
+ return SolidAppContext
33
+ }
34
+
35
+ /**
36
+ * Returns `sym($SolidTestEnvironment.username)` if
37
+ * `$SolidTestEnvironment.username` is defined as a global
38
+ * or
39
+ * returns testID defined in the HTML page
40
+ * @returns {NamedNode|null}
41
+ */
42
+ export function offlineTestID (): NamedNode | null {
43
+ const { $SolidTestEnvironment }: any = window
44
+ if (
45
+ typeof $SolidTestEnvironment !== 'undefined' &&
46
+ $SolidTestEnvironment.username
47
+ ) {
48
+ // Test setup
49
+ debug.log('Assuming the user is ' + $SolidTestEnvironment.username)
50
+ return sym($SolidTestEnvironment.username)
51
+ }
52
+ // hack that makes SolidOS work in offline mode by adding the webId directly in html
53
+ // example usage: https://github.com/solid/mashlib/blob/29b8b53c46bf02e0e219f0bacd51b0e9951001dd/test/contact/local.html#L37
54
+ if (
55
+ typeof document !== 'undefined' &&
56
+ document.location &&
57
+ ('' + document.location).slice(0, 16) === 'http://localhost'
58
+ ) {
59
+ const div = document.getElementById('appTarget')
60
+ if (!div) return null
61
+ const id = div.getAttribute('testID')
62
+ if (!id) return null
63
+ debug.log('Assuming user is ' + id)
64
+ return sym(id)
65
+ }
66
+ return null
67
+ }
@@ -1,7 +1,7 @@
1
- import { LiveStore, NamedNode, Node, st, term } from "rdflib";
2
- import { SolidNamespace } from "../index";
1
+ import { NamedNode, Node, st, term, LiveStore } from "rdflib";
3
2
  import { ProfileLogic } from "../profile/ProfileLogic";
4
- import { newThing } from "../uri";
3
+ import { SolidNamespace } from "../types";
4
+ import { newThing } from "../util/uri";
5
5
  import { determineChatContainer } from "./determineChatContainer";
6
6
 
7
7
  const CHAT_LOCATION_IN_CONTAINER = "index.ttl#this";
File without changes
@@ -1,19 +1,7 @@
1
- // import { v4 as uuid } from "uuid";
2
- import { LiveStore, NamedNode, Node, st, term } from "rdflib";
3
- import { SolidNamespace } from "../index";
1
+ import { NamedNode, LiveStore } from "rdflib";
4
2
  import { ProfileLogic } from "../profile/ProfileLogic";
3
+ import { SolidNamespace } from "../types";
5
4
  import { UtilityLogic } from "../util/UtilityLogic";
6
- // import { newThing } from "../uri";
7
-
8
- interface NewPaneOptions {
9
- me?: NamedNode;
10
- newInstance?: NamedNode;
11
- newBase: string;
12
- }
13
-
14
- interface CreatedPaneOptions {
15
- newInstance: NamedNode;
16
- }
17
5
 
18
6
  /**
19
7
  * Inbox-related logic