solid-logic 4.0.8-0 → 4.0.8-2

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 (171) hide show
  1. package/README.md +3 -4
  2. package/dist/_virtual/_rolldown/runtime.cjs.js +1 -0
  3. package/dist/acl/aclLogic.cjs.js +2 -0
  4. package/dist/acl/aclLogic.cjs.js.map +1 -0
  5. package/dist/acl/aclLogic.esm.js +56 -0
  6. package/dist/acl/aclLogic.esm.js.map +1 -0
  7. package/dist/authSession/authSession.cjs.js +2 -0
  8. package/dist/authSession/authSession.cjs.js.map +1 -0
  9. package/dist/authSession/authSession.esm.js +22 -0
  10. package/dist/authSession/authSession.esm.js.map +1 -0
  11. package/dist/authSession/events.cjs.js +2 -0
  12. package/dist/authSession/events.cjs.js.map +1 -0
  13. package/dist/authSession/events.esm.js +19 -0
  14. package/dist/authSession/events.esm.js.map +1 -0
  15. package/dist/authSession/issuer.cjs.js +2 -0
  16. package/dist/authSession/issuer.cjs.js.map +1 -0
  17. package/dist/authSession/issuer.esm.js +18 -0
  18. package/dist/authSession/issuer.esm.js.map +1 -0
  19. package/dist/authSession/session.cjs.js +2 -0
  20. package/dist/authSession/session.cjs.js.map +1 -0
  21. package/dist/authSession/session.esm.js +102 -0
  22. package/dist/authSession/session.esm.js.map +1 -0
  23. package/dist/authn/SolidAuthnLogic.cjs.js +2 -0
  24. package/dist/authn/SolidAuthnLogic.cjs.js.map +1 -0
  25. package/dist/authn/SolidAuthnLogic.esm.js +104 -0
  26. package/dist/authn/SolidAuthnLogic.esm.js.map +1 -0
  27. package/dist/authn/authUtil.cjs.js +2 -0
  28. package/dist/authn/authUtil.cjs.js.map +1 -0
  29. package/dist/authn/authUtil.esm.js +33 -0
  30. package/dist/authn/authUtil.esm.js.map +1 -0
  31. package/dist/authn/serverLogout.cjs.js +2 -0
  32. package/dist/authn/serverLogout.cjs.js.map +1 -0
  33. package/dist/authn/serverLogout.esm.js +25 -0
  34. package/dist/authn/serverLogout.esm.js.map +1 -0
  35. package/dist/chat/chatLogic.cjs.js +21 -0
  36. package/dist/chat/chatLogic.cjs.js.map +1 -0
  37. package/dist/chat/chatLogic.esm.js +116 -0
  38. package/dist/chat/chatLogic.esm.js.map +1 -0
  39. package/dist/inbox/inboxLogic.cjs.js +2 -0
  40. package/dist/inbox/inboxLogic.cjs.js.map +1 -0
  41. package/dist/inbox/inboxLogic.esm.js +37 -0
  42. package/dist/inbox/inboxLogic.esm.js.map +1 -0
  43. package/dist/index.cjs.js +2 -0
  44. package/dist/index.cjs.js.map +1 -0
  45. package/dist/index.esm.js +13 -0
  46. package/dist/index.esm.js.map +1 -0
  47. package/dist/issuer/issuerLogic.cjs.js +2 -0
  48. package/dist/issuer/issuerLogic.cjs.js.map +1 -0
  49. package/dist/issuer/issuerLogic.esm.js +30 -0
  50. package/dist/issuer/issuerLogic.esm.js.map +1 -0
  51. package/dist/logic/CustomError.cjs.js +2 -0
  52. package/dist/logic/CustomError.cjs.js.map +1 -0
  53. package/dist/logic/CustomError.esm.js +14 -0
  54. package/dist/logic/CustomError.esm.js.map +1 -0
  55. package/dist/logic/solidLogic.cjs.js +2 -0
  56. package/dist/logic/solidLogic.cjs.js.map +1 -0
  57. package/dist/logic/solidLogic.esm.js +47 -0
  58. package/dist/logic/solidLogic.esm.js.map +1 -0
  59. package/dist/logic/solidLogicSingleton.cjs.js +2 -0
  60. package/dist/logic/solidLogicSingleton.cjs.js.map +1 -0
  61. package/dist/logic/solidLogicSingleton.esm.js +19 -0
  62. package/dist/logic/solidLogicSingleton.esm.js.map +1 -0
  63. package/dist/profile/profileAclDocuments.cjs.js +3 -0
  64. package/dist/profile/profileAclDocuments.cjs.js.map +1 -0
  65. package/dist/profile/profileAclDocuments.esm.js +17 -0
  66. package/dist/profile/profileAclDocuments.esm.js.map +1 -0
  67. package/dist/profile/profileDocuments.cjs.js +3 -0
  68. package/dist/profile/profileDocuments.cjs.js.map +1 -0
  69. package/dist/profile/profileDocuments.esm.js +15 -0
  70. package/dist/profile/profileDocuments.esm.js.map +1 -0
  71. package/dist/profile/profileLogic.cjs.js +2 -0
  72. package/dist/profile/profileLogic.cjs.js.map +1 -0
  73. package/dist/profile/profileLogic.esm.js +184 -0
  74. package/dist/profile/profileLogic.esm.js.map +1 -0
  75. package/dist/typeIndex/typeIndexAclDocuments.cjs.js +3 -0
  76. package/dist/typeIndex/typeIndexAclDocuments.cjs.js.map +1 -0
  77. package/dist/typeIndex/typeIndexAclDocuments.esm.js +35 -0
  78. package/dist/typeIndex/typeIndexAclDocuments.esm.js.map +1 -0
  79. package/dist/typeIndex/typeIndexDocuments.cjs.js +4 -0
  80. package/dist/typeIndex/typeIndexDocuments.cjs.js.map +1 -0
  81. package/dist/typeIndex/typeIndexDocuments.esm.js +21 -0
  82. package/dist/typeIndex/typeIndexDocuments.esm.js.map +1 -0
  83. package/dist/typeIndex/typeIndexLogic.cjs.js +2 -0
  84. package/dist/typeIndex/typeIndexLogic.cjs.js.map +1 -0
  85. package/dist/typeIndex/typeIndexLogic.esm.js +185 -0
  86. package/dist/typeIndex/typeIndexLogic.esm.js.map +1 -0
  87. package/dist/util/containerLogic.cjs.js +2 -0
  88. package/dist/util/containerLogic.cjs.js.map +1 -0
  89. package/dist/util/containerLogic.esm.js +37 -0
  90. package/dist/util/containerLogic.esm.js.map +1 -0
  91. package/dist/util/debug.cjs.js +2 -0
  92. package/dist/util/debug.cjs.js.map +1 -0
  93. package/dist/util/debug.esm.js +11 -0
  94. package/dist/util/debug.esm.js.map +1 -0
  95. package/dist/util/ns.cjs.js +2 -0
  96. package/dist/util/ns.cjs.js.map +1 -0
  97. package/dist/util/ns.esm.js +8 -0
  98. package/dist/util/ns.esm.js.map +1 -0
  99. package/dist/util/utilityLogic.cjs.js +6 -0
  100. package/dist/util/utilityLogic.cjs.js.map +1 -0
  101. package/dist/util/utilityLogic.esm.js +149 -0
  102. package/dist/util/utilityLogic.esm.js.map +1 -0
  103. package/dist/util/utils.cjs.js +2 -0
  104. package/dist/util/utils.cjs.js.map +1 -0
  105. package/dist/util/utils.esm.js +22 -0
  106. package/dist/util/utils.esm.js.map +1 -0
  107. package/package.json +25 -31
  108. package/dist/2729812e0bfc062ee77a.js +0 -1
  109. package/dist/a9c30b64ceaae48b72f0.js +0 -2045
  110. package/dist/acl/aclLogic.d.ts +0 -5
  111. package/dist/acl/aclLogic.d.ts.map +0 -1
  112. package/dist/authSession/authSession.d.ts +0 -42
  113. package/dist/authSession/authSession.d.ts.map +0 -1
  114. package/dist/authSession/events.d.ts +0 -24
  115. package/dist/authSession/events.d.ts.map +0 -1
  116. package/dist/authSession/issuer.d.ts +0 -8
  117. package/dist/authSession/issuer.d.ts.map +0 -1
  118. package/dist/authSession/session.d.ts +0 -45
  119. package/dist/authSession/session.d.ts.map +0 -1
  120. package/dist/authn/SolidAuthnLogic.d.ts +0 -42
  121. package/dist/authn/SolidAuthnLogic.d.ts.map +0 -1
  122. package/dist/authn/authUtil.d.ts +0 -17
  123. package/dist/authn/authUtil.d.ts.map +0 -1
  124. package/dist/authn/serverLogout.d.ts +0 -6
  125. package/dist/authn/serverLogout.d.ts.map +0 -1
  126. package/dist/chat/chatLogic.d.ts +0 -3
  127. package/dist/chat/chatLogic.d.ts.map +0 -1
  128. package/dist/inbox/inboxLogic.d.ts +0 -3
  129. package/dist/inbox/inboxLogic.d.ts.map +0 -1
  130. package/dist/index.d.ts +0 -14
  131. package/dist/index.d.ts.map +0 -1
  132. package/dist/issuer/issuerLogic.d.ts +0 -8
  133. package/dist/issuer/issuerLogic.d.ts.map +0 -1
  134. package/dist/logic/CustomError.d.ts +0 -21
  135. package/dist/logic/CustomError.d.ts.map +0 -1
  136. package/dist/logic/solidLogic.d.ts +0 -6
  137. package/dist/logic/solidLogic.d.ts.map +0 -1
  138. package/dist/logic/solidLogicSingleton.d.ts +0 -4
  139. package/dist/logic/solidLogicSingleton.d.ts.map +0 -1
  140. package/dist/profile/profileAclDocuments.d.ts +0 -2
  141. package/dist/profile/profileAclDocuments.d.ts.map +0 -1
  142. package/dist/profile/profileDocuments.d.ts +0 -2
  143. package/dist/profile/profileDocuments.d.ts.map +0 -1
  144. package/dist/profile/profileLogic.d.ts +0 -3
  145. package/dist/profile/profileLogic.d.ts.map +0 -1
  146. package/dist/solid-logic.esm.js +0 -2339
  147. package/dist/solid-logic.esm.js.map +0 -1
  148. package/dist/solid-logic.esm.min.js +0 -2
  149. package/dist/solid-logic.esm.min.js.map +0 -1
  150. package/dist/solid-logic.js +0 -7529
  151. package/dist/solid-logic.js.map +0 -1
  152. package/dist/solid-logic.min.js +0 -2
  153. package/dist/solid-logic.min.js.map +0 -1
  154. package/dist/typeIndex/typeIndexAclDocuments.d.ts +0 -2
  155. package/dist/typeIndex/typeIndexAclDocuments.d.ts.map +0 -1
  156. package/dist/typeIndex/typeIndexDocuments.d.ts +0 -3
  157. package/dist/typeIndex/typeIndexDocuments.d.ts.map +0 -1
  158. package/dist/typeIndex/typeIndexLogic.d.ts +0 -3
  159. package/dist/typeIndex/typeIndexLogic.d.ts.map +0 -1
  160. package/dist/types.d.ts +0 -113
  161. package/dist/types.d.ts.map +0 -1
  162. package/dist/util/containerLogic.d.ts +0 -11
  163. package/dist/util/containerLogic.d.ts.map +0 -1
  164. package/dist/util/debug.d.ts +0 -5
  165. package/dist/util/debug.d.ts.map +0 -1
  166. package/dist/util/ns.d.ts +0 -2
  167. package/dist/util/ns.d.ts.map +0 -1
  168. package/dist/util/utilityLogic.d.ts +0 -17
  169. package/dist/util/utilityLogic.d.ts.map +0 -1
  170. package/dist/util/utils.d.ts +0 -8
  171. package/dist/util/utils.d.ts.map +0 -1
package/README.md CHANGED
@@ -16,7 +16,7 @@ Core business logic of SolidOS which can be used for any webapp as well.
16
16
  npm install solid-logic rdflib
17
17
  ```
18
18
 
19
- > **Important**: `rdflib` is a peer dependency - you must install it separately.
19
+ > **Important**: `rdflib` is still required by the published bundles, so install it alongside `solid-logic` in your app.
20
20
 
21
21
  ### Import in your project (ESM/TypeScript)
22
22
 
@@ -121,10 +121,9 @@ Check the scripts in the `package.json` for build, watch, lint and test.
121
121
 
122
122
  # Used stack
123
123
 
124
- * TypeScript + Babel
125
- * Jest
124
+ * TypeScript + Vite
125
+ * Vitest
126
126
  * ESLint
127
- * Webpack
128
127
 
129
128
  # How to release
130
129
 
@@ -0,0 +1 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));exports.__toESM=s;
@@ -0,0 +1,2 @@
1
+ const e=require("../util/ns.cjs.js");let t=require("rdflib");var n=(0,t.sym)(`http://www.iana.org/assignments/link-relations/acl`);function r(r){let i=e.ns;async function a(e){await r.fetcher.load(e);let t=r.any(e,n);if(!t)throw Error(`No ACL link discovered for ${e}`);return t.value}function o(e,t,i){let a=r.any(r.sym(e),n);return Promise.resolve().then(()=>a||s(e).catch(t=>{throw Error(`Error fetching rel=ACL header for ${e}: ${t}`)})).then(n=>{let a=c(e,t,n.uri,i);if(!r.fetcher)throw Error(`Cannot PUT this, store has no fetcher`);return r.fetcher.webOperation(`PUT`,n.uri,{data:a,contentType:`text/turtle`}).then(e=>{if(!e.ok)throw Error(`Error writing ACL text: `+e.error);return n})})}function s(e){let t=r.fetcher;if(!t)throw Error(`Cannot fetch ACL rel, store has no fetcher`);return t.load(e).then(t=>{if(!t.ok)throw Error(`fetchACLRel: While loading:`+t.error);let i=r.any(r.sym(e),n);if(!i)throw Error(`fetchACLRel: No Link rel=ACL header for `+e);return i})}function c(e,n,r,a={}){let o=a.public||[],s=(0,t.graph)(),c=(0,t.Namespace)(`http://www.w3.org/ns/auth/acl#`),l=s.sym(`${r}#a1`),u=s.sym(r),d=s.sym(e);if(s.add(l,i.rdf(`type`),c(`Authorization`),u),s.add(l,c(`accessTo`),d,u),a.defaultForNew&&s.add(l,c(`default`),d,u),s.add(l,c(`agent`),n,u),s.add(l,c(`mode`),c(`Read`),u),s.add(l,c(`mode`),c(`Write`),u),s.add(l,c(`mode`),c(`Control`),u),o.length){l=s.sym(`${r}#a2`),s.add(l,i.rdf(`type`),c(`Authorization`),u),s.add(l,c(`accessTo`),d,u),s.add(l,c(`agentClass`),i.foaf(`Agent`),u);for(let e=0;e<o.length;e++)s.add(l,c(`mode`),c(o[e]),u)}return(0,t.serialize)(u,s,r)}return{findAclDocUrl:a,setACLUserPublic:o,genACLText:c}}exports.ACL_LINK=n,exports.createAclLogic=r;
2
+ //# sourceMappingURL=aclLogic.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aclLogic.cjs.js","names":[],"sources":["../../src/acl/aclLogic.ts"],"sourcesContent":["import { graph, NamedNode, Namespace, serialize, sym } from 'rdflib'\nimport { AclLogic } from '../types'\nimport { ns as namespace } from '../util/ns'\n\n\nexport const ACL_LINK = sym(\n 'http://www.iana.org/assignments/link-relations/acl'\n)\n\nexport function createAclLogic(store): AclLogic {\n\n const ns = namespace\n \n async function findAclDocUrl(url: NamedNode) {\n await store.fetcher.load(url)\n const docNode = store.any(url, ACL_LINK)\n if (!docNode) {\n throw new Error(`No ACL link discovered for ${url}`)\n }\n return docNode.value\n }\n /**\n * Simple Access Control\n *\n * This function sets up a simple default ACL for a resource, with\n * RWC for the owner, and a specified access (default none) for the public.\n * In all cases owner has read write control.\n * Parameter lists modes allowed to public\n *\n * @param options\n * @param options.public eg ['Read', 'Write']\n *\n * @returns Resolves with aclDoc uri on successful write\n */\n function setACLUserPublic ( \n docURI: string,\n me: NamedNode,\n options: {\n defaultForNew?: boolean,\n public?: []\n }\n ): Promise<NamedNode> {\n const aclDoc = store.any(\n store.sym(docURI),\n ACL_LINK\n )\n\n return Promise.resolve()\n .then(() => {\n if (aclDoc) {\n return aclDoc as NamedNode\n }\n\n return fetchACLRel(docURI).catch(err => {\n throw new Error(`Error fetching rel=ACL header for ${docURI}: ${err}`)\n })\n })\n .then(aclDoc => {\n const aclText = genACLText(docURI, me, aclDoc.uri, options)\n if (!store.fetcher) {\n throw new Error('Cannot PUT this, store has no fetcher')\n }\n return store.fetcher\n .webOperation('PUT', aclDoc.uri, {\n data: aclText,\n contentType: 'text/turtle'\n })\n .then(result => {\n if (!result.ok) {\n throw new Error('Error writing ACL text: ' + result.error)\n }\n\n return aclDoc\n })\n })\n }\n\n /**\n * @param docURI\n * @returns\n */\n function fetchACLRel (docURI: string): Promise<NamedNode> {\n const fetcher = store.fetcher\n if (!fetcher) {\n throw new Error('Cannot fetch ACL rel, store has no fetcher')\n }\n\n return fetcher.load(docURI).then(result => {\n if (!result.ok) {\n throw new Error('fetchACLRel: While loading:' + (result as any).error)\n }\n\n const aclDoc = store.any(\n store.sym(docURI),\n ACL_LINK\n )\n\n if (!aclDoc) {\n throw new Error('fetchACLRel: No Link rel=ACL header for ' + docURI)\n }\n\n return aclDoc as NamedNode\n })\n }\n\n /**\n * @param docURI\n * @param me\n * @param aclURI\n * @param options\n *\n * @returns Serialized ACL\n */\n function genACLText (\n docURI: string,\n me: NamedNode,\n aclURI: string,\n options: {\n defaultForNew?: boolean,\n public?: []\n } = {}\n ): string | undefined {\n const optPublic = options.public || []\n const g = graph()\n const auth = Namespace('http://www.w3.org/ns/auth/acl#')\n let a = g.sym(`${aclURI}#a1`)\n const acl = g.sym(aclURI)\n const doc = g.sym(docURI)\n g.add(a, ns.rdf('type'), auth('Authorization'), acl)\n g.add(a, auth('accessTo'), doc, acl)\n if (options.defaultForNew) {\n g.add(a, auth('default'), doc, acl)\n }\n g.add(a, auth('agent'), me, acl)\n g.add(a, auth('mode'), auth('Read'), acl)\n g.add(a, auth('mode'), auth('Write'), acl)\n g.add(a, auth('mode'), auth('Control'), acl)\n\n if (optPublic.length) {\n a = g.sym(`${aclURI}#a2`)\n g.add(a, ns.rdf('type'), auth('Authorization'), acl)\n g.add(a, auth('accessTo'), doc, acl)\n g.add(a, auth('agentClass'), ns.foaf('Agent'), acl)\n for (let p = 0; p < optPublic.length; p++) {\n g.add(a, auth('mode'), auth(optPublic[p]), acl) // Like 'Read' etc\n }\n }\n return serialize(acl, g, aclURI)\n }\n return {\n findAclDocUrl,\n setACLUserPublic,\n genACLText\n }\n}"],"mappings":"6DAKA,IAAa,GAAA,EAAA,EAAA,IAAA,CACT,oDACJ,EAEA,SAAgB,EAAe,EAAiB,CAE5C,IAAM,EAAK,EAAA,GAEX,eAAe,EAAc,EAAgB,CACzC,MAAM,EAAM,QAAQ,KAAK,CAAG,EAC5B,IAAM,EAAU,EAAM,IAAI,EAAK,CAAQ,EACvC,GAAI,CAAC,EACD,MAAU,MAAM,8BAA8B,GAAK,EAEvD,OAAO,EAAQ,KACnB,CAcA,SAAS,EACT,EACA,EACA,EAIsB,CACtB,IAAM,EAAS,EAAM,IACjB,EAAM,IAAI,CAAM,EAChB,CACJ,EAEA,OAAO,QAAQ,QAAQ,CAAC,CACnB,SACG,GAIG,EAAY,CAAM,CAAC,CAAC,MAAM,GAAO,CACpC,MAAU,MAAM,qCAAqC,EAAO,IAAI,GAAK,CACzE,CAAC,CACA,CAAC,CACD,KAAK,GAAU,CAChB,IAAM,EAAU,EAAW,EAAQ,EAAI,EAAO,IAAK,CAAO,EAC1D,GAAI,CAAC,EAAM,QACP,MAAU,MAAM,uCAAuC,EAE3D,OAAO,EAAM,QACR,aAAa,MAAO,EAAO,IAAK,CACjC,KAAM,EACN,YAAa,aACb,CAAC,CAAC,CACD,KAAK,GAAU,CAChB,GAAI,CAAC,EAAO,GACR,MAAU,MAAM,2BAA6B,EAAO,KAAK,EAG7D,OAAO,CACP,CAAC,CACL,CAAC,CACL,CAMA,SAAS,EAAa,EAAoC,CACtD,IAAM,EAAU,EAAM,QACtB,GAAI,CAAC,EACD,MAAU,MAAM,4CAA4C,EAGhE,OAAO,EAAQ,KAAK,CAAM,CAAC,CAAC,KAAK,GAAU,CACvC,GAAI,CAAC,EAAO,GACR,MAAU,MAAM,8BAAiC,EAAe,KAAK,EAGzE,IAAM,EAAS,EAAM,IACrB,EAAM,IAAI,CAAM,EAChB,CACA,EAEA,GAAI,CAAC,EACL,MAAU,MAAM,2CAA6C,CAAM,EAGnE,OAAO,CACX,CAAC,CACL,CAUA,SAAS,EACT,EACA,EACA,EACA,EAGQ,CAAC,EACa,CAClB,IAAM,EAAY,EAAQ,QAAU,CAAC,EAC/B,GAAA,EAAA,EAAA,MAAA,CAAU,EACV,GAAA,EAAA,EAAA,UAAA,CAAiB,gCAAgC,EACnD,EAAI,EAAE,IAAI,GAAG,EAAO,IAAI,EACtB,EAAM,EAAE,IAAI,CAAM,EAClB,EAAM,EAAE,IAAI,CAAM,EAWxB,GAVA,EAAE,IAAI,EAAG,EAAG,IAAI,MAAM,EAAG,EAAK,eAAe,EAAG,CAAG,EACnD,EAAE,IAAI,EAAG,EAAK,UAAU,EAAG,EAAK,CAAG,EAC/B,EAAQ,eACR,EAAE,IAAI,EAAG,EAAK,SAAS,EAAG,EAAK,CAAG,EAEtC,EAAE,IAAI,EAAG,EAAK,OAAO,EAAG,EAAI,CAAG,EAC/B,EAAE,IAAI,EAAG,EAAK,MAAM,EAAG,EAAK,MAAM,EAAG,CAAG,EACxC,EAAE,IAAI,EAAG,EAAK,MAAM,EAAG,EAAK,OAAO,EAAG,CAAG,EACzC,EAAE,IAAI,EAAG,EAAK,MAAM,EAAG,EAAK,SAAS,EAAG,CAAG,EAEvC,EAAU,OAAQ,CAClB,EAAI,EAAE,IAAI,GAAG,EAAO,IAAI,EACxB,EAAE,IAAI,EAAG,EAAG,IAAI,MAAM,EAAG,EAAK,eAAe,EAAG,CAAG,EACnD,EAAE,IAAI,EAAG,EAAK,UAAU,EAAG,EAAK,CAAG,EACnC,EAAE,IAAI,EAAG,EAAK,YAAY,EAAG,EAAG,KAAK,OAAO,EAAG,CAAG,EAClD,IAAK,IAAI,EAAI,EAAG,EAAI,EAAU,OAAQ,IACtC,EAAE,IAAI,EAAG,EAAK,MAAM,EAAG,EAAK,EAAU,EAAE,EAAG,CAAG,CAElD,CACA,OAAA,EAAA,EAAA,UAAA,CAAiB,EAAK,EAAG,CAAM,CACnC,CACA,MAAO,CACH,gBACA,mBACA,YACJ,CACJ"}
@@ -0,0 +1,56 @@
1
+ import { ns as e } from "../util/ns.esm.js";
2
+ import { Namespace as t, graph as n, serialize as r, sym as i } from "rdflib";
3
+ //#region src/acl/aclLogic.ts
4
+ var a = i("http://www.iana.org/assignments/link-relations/acl");
5
+ function o(i) {
6
+ let o = e;
7
+ async function s(e) {
8
+ await i.fetcher.load(e);
9
+ let t = i.any(e, a);
10
+ if (!t) throw Error(`No ACL link discovered for ${e}`);
11
+ return t.value;
12
+ }
13
+ function c(e, t, n) {
14
+ let r = i.any(i.sym(e), a);
15
+ return Promise.resolve().then(() => r || l(e).catch((t) => {
16
+ throw Error(`Error fetching rel=ACL header for ${e}: ${t}`);
17
+ })).then((r) => {
18
+ let a = u(e, t, r.uri, n);
19
+ if (!i.fetcher) throw Error("Cannot PUT this, store has no fetcher");
20
+ return i.fetcher.webOperation("PUT", r.uri, {
21
+ data: a,
22
+ contentType: "text/turtle"
23
+ }).then((e) => {
24
+ if (!e.ok) throw Error("Error writing ACL text: " + e.error);
25
+ return r;
26
+ });
27
+ });
28
+ }
29
+ function l(e) {
30
+ let t = i.fetcher;
31
+ if (!t) throw Error("Cannot fetch ACL rel, store has no fetcher");
32
+ return t.load(e).then((t) => {
33
+ if (!t.ok) throw Error("fetchACLRel: While loading:" + t.error);
34
+ let n = i.any(i.sym(e), a);
35
+ if (!n) throw Error("fetchACLRel: No Link rel=ACL header for " + e);
36
+ return n;
37
+ });
38
+ }
39
+ function u(e, i, a, s = {}) {
40
+ let c = s.public || [], l = n(), u = t("http://www.w3.org/ns/auth/acl#"), d = l.sym(`${a}#a1`), f = l.sym(a), p = l.sym(e);
41
+ if (l.add(d, o.rdf("type"), u("Authorization"), f), l.add(d, u("accessTo"), p, f), s.defaultForNew && l.add(d, u("default"), p, f), l.add(d, u("agent"), i, f), l.add(d, u("mode"), u("Read"), f), l.add(d, u("mode"), u("Write"), f), l.add(d, u("mode"), u("Control"), f), c.length) {
42
+ d = l.sym(`${a}#a2`), l.add(d, o.rdf("type"), u("Authorization"), f), l.add(d, u("accessTo"), p, f), l.add(d, u("agentClass"), o.foaf("Agent"), f);
43
+ for (let e = 0; e < c.length; e++) l.add(d, u("mode"), u(c[e]), f);
44
+ }
45
+ return r(f, l, a);
46
+ }
47
+ return {
48
+ findAclDocUrl: s,
49
+ setACLUserPublic: c,
50
+ genACLText: u
51
+ };
52
+ }
53
+ //#endregion
54
+ export { a as ACL_LINK, o as createAclLogic };
55
+
56
+ //# sourceMappingURL=aclLogic.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aclLogic.esm.js","names":[],"sources":["../../src/acl/aclLogic.ts"],"sourcesContent":["import { graph, NamedNode, Namespace, serialize, sym } from 'rdflib'\nimport { AclLogic } from '../types'\nimport { ns as namespace } from '../util/ns'\n\n\nexport const ACL_LINK = sym(\n 'http://www.iana.org/assignments/link-relations/acl'\n)\n\nexport function createAclLogic(store): AclLogic {\n\n const ns = namespace\n \n async function findAclDocUrl(url: NamedNode) {\n await store.fetcher.load(url)\n const docNode = store.any(url, ACL_LINK)\n if (!docNode) {\n throw new Error(`No ACL link discovered for ${url}`)\n }\n return docNode.value\n }\n /**\n * Simple Access Control\n *\n * This function sets up a simple default ACL for a resource, with\n * RWC for the owner, and a specified access (default none) for the public.\n * In all cases owner has read write control.\n * Parameter lists modes allowed to public\n *\n * @param options\n * @param options.public eg ['Read', 'Write']\n *\n * @returns Resolves with aclDoc uri on successful write\n */\n function setACLUserPublic ( \n docURI: string,\n me: NamedNode,\n options: {\n defaultForNew?: boolean,\n public?: []\n }\n ): Promise<NamedNode> {\n const aclDoc = store.any(\n store.sym(docURI),\n ACL_LINK\n )\n\n return Promise.resolve()\n .then(() => {\n if (aclDoc) {\n return aclDoc as NamedNode\n }\n\n return fetchACLRel(docURI).catch(err => {\n throw new Error(`Error fetching rel=ACL header for ${docURI}: ${err}`)\n })\n })\n .then(aclDoc => {\n const aclText = genACLText(docURI, me, aclDoc.uri, options)\n if (!store.fetcher) {\n throw new Error('Cannot PUT this, store has no fetcher')\n }\n return store.fetcher\n .webOperation('PUT', aclDoc.uri, {\n data: aclText,\n contentType: 'text/turtle'\n })\n .then(result => {\n if (!result.ok) {\n throw new Error('Error writing ACL text: ' + result.error)\n }\n\n return aclDoc\n })\n })\n }\n\n /**\n * @param docURI\n * @returns\n */\n function fetchACLRel (docURI: string): Promise<NamedNode> {\n const fetcher = store.fetcher\n if (!fetcher) {\n throw new Error('Cannot fetch ACL rel, store has no fetcher')\n }\n\n return fetcher.load(docURI).then(result => {\n if (!result.ok) {\n throw new Error('fetchACLRel: While loading:' + (result as any).error)\n }\n\n const aclDoc = store.any(\n store.sym(docURI),\n ACL_LINK\n )\n\n if (!aclDoc) {\n throw new Error('fetchACLRel: No Link rel=ACL header for ' + docURI)\n }\n\n return aclDoc as NamedNode\n })\n }\n\n /**\n * @param docURI\n * @param me\n * @param aclURI\n * @param options\n *\n * @returns Serialized ACL\n */\n function genACLText (\n docURI: string,\n me: NamedNode,\n aclURI: string,\n options: {\n defaultForNew?: boolean,\n public?: []\n } = {}\n ): string | undefined {\n const optPublic = options.public || []\n const g = graph()\n const auth = Namespace('http://www.w3.org/ns/auth/acl#')\n let a = g.sym(`${aclURI}#a1`)\n const acl = g.sym(aclURI)\n const doc = g.sym(docURI)\n g.add(a, ns.rdf('type'), auth('Authorization'), acl)\n g.add(a, auth('accessTo'), doc, acl)\n if (options.defaultForNew) {\n g.add(a, auth('default'), doc, acl)\n }\n g.add(a, auth('agent'), me, acl)\n g.add(a, auth('mode'), auth('Read'), acl)\n g.add(a, auth('mode'), auth('Write'), acl)\n g.add(a, auth('mode'), auth('Control'), acl)\n\n if (optPublic.length) {\n a = g.sym(`${aclURI}#a2`)\n g.add(a, ns.rdf('type'), auth('Authorization'), acl)\n g.add(a, auth('accessTo'), doc, acl)\n g.add(a, auth('agentClass'), ns.foaf('Agent'), acl)\n for (let p = 0; p < optPublic.length; p++) {\n g.add(a, auth('mode'), auth(optPublic[p]), acl) // Like 'Read' etc\n }\n }\n return serialize(acl, g, aclURI)\n }\n return {\n findAclDocUrl,\n setACLUserPublic,\n genACLText\n }\n}"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require("./session.cjs.js"),t=require("./issuer.cjs.js"),n=require("./events.cjs.js");var r=e._session,i=typeof r.login==`function`?r.login.bind(e._session):void 0;i&&(r.login=async(e,n)=>{if(e&&typeof e==`object`&&!Array.isArray(e)){let n=e.oidcIssuer??e.idp??e.issuer,r=e.redirectUrl??e.redirect_uri??e.redirectUri;if(typeof n==`string`&&typeof r==`string`)return i(await t.resolveIssuerForLogin(n),r)}return i(typeof e==`string`?await t.resolveIssuerForLogin(e):e,n)});var a=new n.SessionEvents,o=e._session.isActive??!!e._session.webId;typeof e._session.addEventListener==`function`&&e._session.addEventListener(`sessionStateChange`,()=>{let t=e._session.isActive??!!e._session.webId;o&&!t&&a.emit(`logout`),o=t});var s=Object.assign(e._session,{events:a});exports.authSession=s;
2
+ //# sourceMappingURL=authSession.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authSession.cjs.js","names":[],"sources":["../../src/authSession/authSession.ts"],"sourcesContent":["/**\n * Auth session wiring.\n *\n * Takes the raw OIDC session from session.ts and layers on:\n * - Login compatibility shim (normalises legacy call-site signatures\n * and resolves the canonical issuer)\n * - SessionEvents shim (legacy EventEmitter-style API)\n * - Logout listener (emits 'logout' on session deactivation)\n *\n * Exports the fully assembled authSession.\n */\n\nimport type { Session as OidcSession } from '@uvdsl/solid-oidc-client-browser/core'\nimport { _session } from './session'\nimport { resolveIssuerForLogin } from './issuer'\nimport { SessionEvents } from './events'\n\ntype SessionCompatibilityShape = {\n webId?: string\n isActive?: boolean\n info?: {\n webId?: string\n isLoggedIn?: boolean\n }\n fetch?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>\n authFetch?: (input: string | URL | Request, init?: RequestInit, dpopPayload?: any) => Promise<Response>\n}\n\ntype LoginOptionsLegacy = {\n oidcIssuer?: string\n idp?: string\n issuer?: string\n redirectUrl?: string\n redirect_uri?: string\n redirectUri?: string\n}\n\ntype LoginCompat = {\n (issuer: string, redirectUrl: string): Promise<unknown>\n (options: LoginOptionsLegacy): Promise<unknown>\n}\n\nexport type SessionWithLegacyEvents = Omit<OidcSession, 'login'> & SessionCompatibilityShape & {\n login: LoginCompat\n events: SessionEvents\n}\n\n// ---------------------------------------------------------------------------\n// Login compatibility shim\n// ---------------------------------------------------------------------------\n// Wraps _session.login() so that call sites with different calling\n// conventions all work. The underlying session expects:\n// login(issuer: string, redirectUrl: string)\n//\n// idpOrOptions can be:\n// - a string (issuer URL) — passed through with less resolution\n// - an options object with any of these field-name variants:\n// issuer: oidcIssuer | idp | issuer\n// redirect: redirectUrl | redirect_uri | redirectUri\n// (all redirect field names map to the same value: the URL the IdP\n// should send the browser back to after authentication)\n// - anything else — passed through to the underlying session as-is\n//\n// In all cases the issuer is resolved through\n// /.well-known/openid-configuration before redirect so the canonical\n// issuer host is used.\n\nconst sessionAny = _session as any\nconst originalLogin = typeof sessionAny.login === 'function'\n ? sessionAny.login.bind(_session)\n : undefined\n\nif (originalLogin) {\n const compatLogin = async (idpOrOptions: any, redirectUri?: string): Promise<unknown> => {\n if (idpOrOptions && typeof idpOrOptions === 'object' && !Array.isArray(idpOrOptions)) {\n const oidcIssuer = idpOrOptions.oidcIssuer ?? idpOrOptions.idp ?? idpOrOptions.issuer\n const redirectUrl = idpOrOptions.redirectUrl ?? idpOrOptions.redirect_uri ?? idpOrOptions.redirectUri\n if (typeof oidcIssuer === 'string' && typeof redirectUrl === 'string') {\n return originalLogin(await resolveIssuerForLogin(oidcIssuer), redirectUrl)\n }\n }\n if (typeof idpOrOptions === 'string') {\n return originalLogin(await resolveIssuerForLogin(idpOrOptions), redirectUri)\n }\n return originalLogin(idpOrOptions, redirectUri)\n }\n sessionAny.login = compatLogin as LoginCompat\n}\n\n// ---------------------------------------------------------------------------\n// Legacy event layer\n// ---------------------------------------------------------------------------\n\nconst events = new SessionEvents()\n\n// Emit the legacy 'logout' event when the session transitions from active to inactive.\n// 'login' and 'sessionRestore' are emitted in SolidAuthnLogic.checkUser()\n// because only that call site knows which path activated the session.\nlet _wasActive = (_session as any).isActive ?? Boolean((_session as any).webId)\nif (typeof (_session as unknown as EventTarget).addEventListener === 'function') {\n ;(_session as unknown as EventTarget).addEventListener('sessionStateChange', () => {\n const isNowActive = (_session as any).isActive ?? Boolean((_session as any).webId)\n if (_wasActive && !isNowActive) {\n events.emit('logout')\n }\n _wasActive = isNowActive\n })\n}\n\nexport const authSession: SessionWithLegacyEvents = Object.assign(\n _session as Omit<OidcSession, 'login'> & { login: LoginCompat },\n { events }\n)\n "],"mappings":"8FAmEA,IAAM,EAAa,EAAA,SACb,EAAgB,OAAO,EAAW,OAAU,WAC9C,EAAW,MAAM,KAAK,EAAA,QAAQ,EAC9B,IAAA,GAEA,IAcF,EAAW,MAAQ,MAbQ,EAAmB,IAA2C,CACvF,GAAI,GAAgB,OAAO,GAAiB,UAAY,CAAC,MAAM,QAAQ,CAAY,EAAG,CACpF,IAAM,EAAa,EAAa,YAAc,EAAa,KAAO,EAAa,OACzE,EAAc,EAAa,aAAe,EAAa,cAAgB,EAAa,YAC1F,GAAI,OAAO,GAAe,UAAY,OAAO,GAAgB,SAC3D,OAAO,EAAc,MAAM,EAAA,sBAAsB,CAAU,EAAG,CAAW,CAE7E,CAIA,OAFS,EADL,OAAO,GAAiB,SACL,MAAM,EAAA,sBAAsB,CAAY,EAE1C,EAF6C,CAAW,CAG/E,GAQF,IAAM,EAAS,IAAI,EAAA,cAKf,EAAc,EAAA,SAAiB,UAAY,EAAS,EAAA,SAAiB,MACrE,OAAQ,EAAA,SAAoC,kBAAqB,YAClE,EAAA,SAAqC,iBAAiB,yBAA4B,CACjF,IAAM,EAAe,EAAA,SAAiB,UAAY,EAAS,EAAA,SAAiB,MACxE,GAAc,CAAC,GACjB,EAAO,KAAK,QAAQ,EAEtB,EAAa,CACf,CAAC,EAGH,IAAa,EAAuC,OAAO,OACzD,EAAA,SACA,CAAE,QAAO,CACX"}
@@ -0,0 +1,22 @@
1
+ import { _session as e } from "./session.esm.js";
2
+ import { resolveIssuerForLogin as t } from "./issuer.esm.js";
3
+ import { SessionEvents as n } from "./events.esm.js";
4
+ //#region src/authSession/authSession.ts
5
+ var r = e, i = typeof r.login == "function" ? r.login.bind(e) : void 0;
6
+ i && (r.login = async (e, n) => {
7
+ if (e && typeof e == "object" && !Array.isArray(e)) {
8
+ let n = e.oidcIssuer ?? e.idp ?? e.issuer, r = e.redirectUrl ?? e.redirect_uri ?? e.redirectUri;
9
+ if (typeof n == "string" && typeof r == "string") return i(await t(n), r);
10
+ }
11
+ return i(typeof e == "string" ? await t(e) : e, n);
12
+ });
13
+ var a = new n(), o = e.isActive ?? !!e.webId;
14
+ typeof e.addEventListener == "function" && e.addEventListener("sessionStateChange", () => {
15
+ let t = e.isActive ?? !!e.webId;
16
+ o && !t && a.emit("logout"), o = t;
17
+ });
18
+ var s = Object.assign(e, { events: a });
19
+ //#endregion
20
+ export { s as authSession };
21
+
22
+ //# sourceMappingURL=authSession.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authSession.esm.js","names":[],"sources":["../../src/authSession/authSession.ts"],"sourcesContent":["/**\n * Auth session wiring.\n *\n * Takes the raw OIDC session from session.ts and layers on:\n * - Login compatibility shim (normalises legacy call-site signatures\n * and resolves the canonical issuer)\n * - SessionEvents shim (legacy EventEmitter-style API)\n * - Logout listener (emits 'logout' on session deactivation)\n *\n * Exports the fully assembled authSession.\n */\n\nimport type { Session as OidcSession } from '@uvdsl/solid-oidc-client-browser/core'\nimport { _session } from './session'\nimport { resolveIssuerForLogin } from './issuer'\nimport { SessionEvents } from './events'\n\ntype SessionCompatibilityShape = {\n webId?: string\n isActive?: boolean\n info?: {\n webId?: string\n isLoggedIn?: boolean\n }\n fetch?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>\n authFetch?: (input: string | URL | Request, init?: RequestInit, dpopPayload?: any) => Promise<Response>\n}\n\ntype LoginOptionsLegacy = {\n oidcIssuer?: string\n idp?: string\n issuer?: string\n redirectUrl?: string\n redirect_uri?: string\n redirectUri?: string\n}\n\ntype LoginCompat = {\n (issuer: string, redirectUrl: string): Promise<unknown>\n (options: LoginOptionsLegacy): Promise<unknown>\n}\n\nexport type SessionWithLegacyEvents = Omit<OidcSession, 'login'> & SessionCompatibilityShape & {\n login: LoginCompat\n events: SessionEvents\n}\n\n// ---------------------------------------------------------------------------\n// Login compatibility shim\n// ---------------------------------------------------------------------------\n// Wraps _session.login() so that call sites with different calling\n// conventions all work. The underlying session expects:\n// login(issuer: string, redirectUrl: string)\n//\n// idpOrOptions can be:\n// - a string (issuer URL) — passed through with less resolution\n// - an options object with any of these field-name variants:\n// issuer: oidcIssuer | idp | issuer\n// redirect: redirectUrl | redirect_uri | redirectUri\n// (all redirect field names map to the same value: the URL the IdP\n// should send the browser back to after authentication)\n// - anything else — passed through to the underlying session as-is\n//\n// In all cases the issuer is resolved through\n// /.well-known/openid-configuration before redirect so the canonical\n// issuer host is used.\n\nconst sessionAny = _session as any\nconst originalLogin = typeof sessionAny.login === 'function'\n ? sessionAny.login.bind(_session)\n : undefined\n\nif (originalLogin) {\n const compatLogin = async (idpOrOptions: any, redirectUri?: string): Promise<unknown> => {\n if (idpOrOptions && typeof idpOrOptions === 'object' && !Array.isArray(idpOrOptions)) {\n const oidcIssuer = idpOrOptions.oidcIssuer ?? idpOrOptions.idp ?? idpOrOptions.issuer\n const redirectUrl = idpOrOptions.redirectUrl ?? idpOrOptions.redirect_uri ?? idpOrOptions.redirectUri\n if (typeof oidcIssuer === 'string' && typeof redirectUrl === 'string') {\n return originalLogin(await resolveIssuerForLogin(oidcIssuer), redirectUrl)\n }\n }\n if (typeof idpOrOptions === 'string') {\n return originalLogin(await resolveIssuerForLogin(idpOrOptions), redirectUri)\n }\n return originalLogin(idpOrOptions, redirectUri)\n }\n sessionAny.login = compatLogin as LoginCompat\n}\n\n// ---------------------------------------------------------------------------\n// Legacy event layer\n// ---------------------------------------------------------------------------\n\nconst events = new SessionEvents()\n\n// Emit the legacy 'logout' event when the session transitions from active to inactive.\n// 'login' and 'sessionRestore' are emitted in SolidAuthnLogic.checkUser()\n// because only that call site knows which path activated the session.\nlet _wasActive = (_session as any).isActive ?? Boolean((_session as any).webId)\nif (typeof (_session as unknown as EventTarget).addEventListener === 'function') {\n ;(_session as unknown as EventTarget).addEventListener('sessionStateChange', () => {\n const isNowActive = (_session as any).isActive ?? Boolean((_session as any).webId)\n if (_wasActive && !isNowActive) {\n events.emit('logout')\n }\n _wasActive = isNowActive\n })\n}\n\nexport const authSession: SessionWithLegacyEvents = Object.assign(\n _session as Omit<OidcSession, 'login'> & { login: LoginCompat },\n { events }\n)\n "],"mappings":";;;;AAmEA,IAAM,IAAa,GACb,IAAgB,OAAO,EAAW,SAAU,aAC9C,EAAW,MAAM,KAAK,CAAQ,IAC9B,KAAA;AAEA,MAcF,EAAW,QAAQ,OAbQ,GAAmB,MAA2C;CACvF,IAAI,KAAgB,OAAO,KAAiB,YAAY,CAAC,MAAM,QAAQ,CAAY,GAAG;EACpF,IAAM,IAAa,EAAa,cAAc,EAAa,OAAO,EAAa,QACzE,IAAc,EAAa,eAAe,EAAa,gBAAgB,EAAa;EAC1F,IAAI,OAAO,KAAe,YAAY,OAAO,KAAgB,UAC3D,OAAO,EAAc,MAAM,EAAsB,CAAU,GAAG,CAAW;CAE7E;CAIA,OAFS,EADL,OAAO,KAAiB,WACL,MAAM,EAAsB,CAAY,IAE1C,GAF6C,CAAW;AAG/E;AAQF,IAAM,IAAS,IAAI,EAAc,GAK7B,IAAc,EAAiB,YAAY,EAAS,EAAiB;AACrE,OAAQ,EAAoC,oBAAqB,cAClE,EAAqC,iBAAiB,4BAA4B;CACjF,IAAM,IAAe,EAAiB,YAAY,EAAS,EAAiB;CAI5E,AAHI,KAAc,CAAC,KACjB,EAAO,KAAK,QAAQ,GAEtB,IAAa;AACf,CAAC;AAGH,IAAa,IAAuC,OAAO,OACzD,GACA,EAAE,UAAO,CACX"}
@@ -0,0 +1,2 @@
1
+ var e=class{constructor(){this.listeners=new Map}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t)}off(e,t){this.listeners.get(e)?.delete(t)}emit(e,...t){this.listeners.get(e)?.forEach(e=>e(...t))}};exports.SessionEvents=e;
2
+ //# sourceMappingURL=events.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.cjs.js","names":[],"sources":["../../src/authSession/events.ts"],"sourcesContent":["/**\n * Legacy event compatibility layer.\n *\n * Pure EventEmitter-style shim — no side effects, no uvdsl dependencies.\n * Wired into the auth session by authSession.ts.\n */\n\ntype LegacyEventName = 'login' | 'logout' | 'sessionRestore'\ntype LegacyEventHandler = (...args: unknown[]) => void\n\n/**\n * Minimal EventEmitter-style shim so that existing consumers using\n * `authSession.events.on('login' | 'logout' | 'sessionRestore', handler)`\n * continue working without modification.\n *\n * Events are emitted by SolidAuthnLogic.checkUser() (login/sessionRestore)\n * and by the sessionStateChange listener in authSession.ts (logout).\n */\nexport class SessionEvents {\n private readonly listeners: Map<string, Set<LegacyEventHandler>> = new Map()\n\n on (event: LegacyEventName, handler: LegacyEventHandler): void {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set())\n this.listeners.get(event)!.add(handler)\n }\n\n off (event: LegacyEventName, handler: LegacyEventHandler): void {\n this.listeners.get(event)?.delete(handler)\n }\n\n emit (event: LegacyEventName, ...args: unknown[]): void {\n this.listeners.get(event)?.forEach(h => h(...args))\n }\n}\n\n"],"mappings":"AAkBA,IAAa,EAAb,KAA2B,8BAC0C,IAAI,IAEvE,GAAI,EAAwB,EAAmC,CACxD,KAAK,UAAU,IAAI,CAAK,GAAG,KAAK,UAAU,IAAI,EAAO,IAAI,GAAK,EACnE,KAAK,UAAU,IAAI,CAAK,CAAC,CAAE,IAAI,CAAO,CACxC,CAEA,IAAK,EAAwB,EAAmC,CAC9D,KAAK,UAAU,IAAI,CAAK,CAAC,EAAE,OAAO,CAAO,CAC3C,CAEA,KAAM,EAAwB,GAAG,EAAuB,CACtD,KAAK,UAAU,IAAI,CAAK,CAAC,EAAE,QAAQ,GAAK,EAAE,GAAG,CAAI,CAAC,CACpD,CACF"}
@@ -0,0 +1,19 @@
1
+ //#region src/authSession/events.ts
2
+ var e = class {
3
+ constructor() {
4
+ this.listeners = /* @__PURE__ */ new Map();
5
+ }
6
+ on(e, t) {
7
+ this.listeners.has(e) || this.listeners.set(e, /* @__PURE__ */ new Set()), this.listeners.get(e).add(t);
8
+ }
9
+ off(e, t) {
10
+ this.listeners.get(e)?.delete(t);
11
+ }
12
+ emit(e, ...t) {
13
+ this.listeners.get(e)?.forEach((e) => e(...t));
14
+ }
15
+ };
16
+ //#endregion
17
+ export { e as SessionEvents };
18
+
19
+ //# sourceMappingURL=events.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.esm.js","names":[],"sources":["../../src/authSession/events.ts"],"sourcesContent":["/**\n * Legacy event compatibility layer.\n *\n * Pure EventEmitter-style shim — no side effects, no uvdsl dependencies.\n * Wired into the auth session by authSession.ts.\n */\n\ntype LegacyEventName = 'login' | 'logout' | 'sessionRestore'\ntype LegacyEventHandler = (...args: unknown[]) => void\n\n/**\n * Minimal EventEmitter-style shim so that existing consumers using\n * `authSession.events.on('login' | 'logout' | 'sessionRestore', handler)`\n * continue working without modification.\n *\n * Events are emitted by SolidAuthnLogic.checkUser() (login/sessionRestore)\n * and by the sessionStateChange listener in authSession.ts (logout).\n */\nexport class SessionEvents {\n private readonly listeners: Map<string, Set<LegacyEventHandler>> = new Map()\n\n on (event: LegacyEventName, handler: LegacyEventHandler): void {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set())\n this.listeners.get(event)!.add(handler)\n }\n\n off (event: LegacyEventName, handler: LegacyEventHandler): void {\n this.listeners.get(event)?.delete(handler)\n }\n\n emit (event: LegacyEventName, ...args: unknown[]): void {\n this.listeners.get(event)?.forEach(h => h(...args))\n }\n}\n\n"],"mappings":";AAkBA,IAAa,IAAb,MAA2B;;mCAC0C,IAAI,IAAI;;CAE3E,GAAI,GAAwB,GAAmC;EAE7D,AADK,KAAK,UAAU,IAAI,CAAK,KAAG,KAAK,UAAU,IAAI,mBAAO,IAAI,IAAI,CAAC,GACnE,KAAK,UAAU,IAAI,CAAK,CAAC,CAAE,IAAI,CAAO;CACxC;CAEA,IAAK,GAAwB,GAAmC;EAC9D,KAAK,UAAU,IAAI,CAAK,CAAC,EAAE,OAAO,CAAO;CAC3C;CAEA,KAAM,GAAwB,GAAG,GAAuB;EACtD,KAAK,UAAU,IAAI,CAAK,CAAC,EAAE,SAAQ,MAAK,EAAE,GAAG,CAAI,CAAC;CACpD;AACF"}
@@ -0,0 +1,2 @@
1
+ async function e(e){try{let t=new URL(e),n=new URL(`/.well-known/openid-configuration`,t.origin),r=await fetch(n.toString(),{credentials:`include`});if(!r.ok)return null;let i=await r.json();return typeof i?.issuer!=`string`||!i.issuer?null:i.issuer.replace(/\/$/,``)}catch{return null}}async function t(t){return await e(t)||t}exports.resolveIssuerForLogin=t;
2
+ //# sourceMappingURL=issuer.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issuer.cjs.js","names":[],"sources":["../../src/authSession/issuer.ts"],"sourcesContent":["/**\n * Issuer discovery utilities.\n *\n * Resolves OIDC issuer endpoints from /.well-known/openid-configuration\n * so that login can use the canonical issuer host.\n */\n\nasync function discoverIssuerFromWellKnown (issuer: string): Promise<string | null> {\n try {\n const issuerUrl = new URL(issuer)\n const wellKnownUrl = new URL('/.well-known/openid-configuration', issuerUrl.origin)\n const wellKnownResponse = await fetch(wellKnownUrl.toString(), { credentials: 'include' })\n if (!wellKnownResponse.ok) {\n return null\n }\n\n const wellKnownPayload = await wellKnownResponse.json()\n if (typeof wellKnownPayload?.issuer !== 'string' || !wellKnownPayload.issuer) {\n return null\n }\n\n return wellKnownPayload.issuer.replace(/\\/$/, '')\n } catch (_err) {\n return null\n }\n}\n\nexport async function resolveIssuerForLogin (issuer: string): Promise<string> {\n // Prefer the issuer advertised by discovery; if app and issuer hosts still differ,\n // redirecting to the canonical issuer host is cleaner than rewriting the issuer here.\n const discoveredIssuer = await discoverIssuerFromWellKnown(issuer)\n if (discoveredIssuer) {\n return discoveredIssuer\n }\n return issuer\n}\n"],"mappings":"AAOA,eAAe,EAA6B,EAAwC,CAClF,GAAI,CACF,IAAM,EAAY,IAAI,IAAI,CAAM,EAC1B,EAAe,IAAI,IAAI,oCAAqC,EAAU,MAAM,EAC5E,EAAoB,MAAM,MAAM,EAAa,SAAS,EAAG,CAAE,YAAa,SAAU,CAAC,EACzF,GAAI,CAAC,EAAkB,GACrB,OAAO,KAGT,IAAM,EAAmB,MAAM,EAAkB,KAAK,EAKtD,OAJI,OAAO,GAAkB,QAAW,UAAY,CAAC,EAAiB,OAC7D,KAGF,EAAiB,OAAO,QAAQ,MAAO,EAAE,CAClD,MAAe,CACb,OAAO,IACT,CACF,CAEA,eAAsB,EAAuB,EAAiC,CAO5E,OAHI,MAD2B,EAA4B,CAAM,GAI1D,CACT"}
@@ -0,0 +1,18 @@
1
+ //#region src/authSession/issuer.ts
2
+ async function e(e) {
3
+ try {
4
+ let t = new URL(e), n = new URL("/.well-known/openid-configuration", t.origin), r = await fetch(n.toString(), { credentials: "include" });
5
+ if (!r.ok) return null;
6
+ let i = await r.json();
7
+ return typeof i?.issuer != "string" || !i.issuer ? null : i.issuer.replace(/\/$/, "");
8
+ } catch {
9
+ return null;
10
+ }
11
+ }
12
+ async function t(t) {
13
+ return await e(t) || t;
14
+ }
15
+ //#endregion
16
+ export { t as resolveIssuerForLogin };
17
+
18
+ //# sourceMappingURL=issuer.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issuer.esm.js","names":[],"sources":["../../src/authSession/issuer.ts"],"sourcesContent":["/**\n * Issuer discovery utilities.\n *\n * Resolves OIDC issuer endpoints from /.well-known/openid-configuration\n * so that login can use the canonical issuer host.\n */\n\nasync function discoverIssuerFromWellKnown (issuer: string): Promise<string | null> {\n try {\n const issuerUrl = new URL(issuer)\n const wellKnownUrl = new URL('/.well-known/openid-configuration', issuerUrl.origin)\n const wellKnownResponse = await fetch(wellKnownUrl.toString(), { credentials: 'include' })\n if (!wellKnownResponse.ok) {\n return null\n }\n\n const wellKnownPayload = await wellKnownResponse.json()\n if (typeof wellKnownPayload?.issuer !== 'string' || !wellKnownPayload.issuer) {\n return null\n }\n\n return wellKnownPayload.issuer.replace(/\\/$/, '')\n } catch (_err) {\n return null\n }\n}\n\nexport async function resolveIssuerForLogin (issuer: string): Promise<string> {\n // Prefer the issuer advertised by discovery; if app and issuer hosts still differ,\n // redirecting to the canonical issuer host is cleaner than rewriting the issuer here.\n const discoveredIssuer = await discoverIssuerFromWellKnown(issuer)\n if (discoveredIssuer) {\n return discoveredIssuer\n }\n return issuer\n}\n"],"mappings":";AAOA,eAAe,EAA6B,GAAwC;CAClF,IAAI;EACF,IAAM,IAAY,IAAI,IAAI,CAAM,GAC1B,IAAe,IAAI,IAAI,qCAAqC,EAAU,MAAM,GAC5E,IAAoB,MAAM,MAAM,EAAa,SAAS,GAAG,EAAE,aAAa,UAAU,CAAC;EACzF,IAAI,CAAC,EAAkB,IACrB,OAAO;EAGT,IAAM,IAAmB,MAAM,EAAkB,KAAK;EAKtD,OAJI,OAAO,GAAkB,UAAW,YAAY,CAAC,EAAiB,SAC7D,OAGF,EAAiB,OAAO,QAAQ,OAAO,EAAE;CAClD,QAAe;EACb,OAAO;CACT;AACF;AAEA,eAAsB,EAAuB,GAAiC;CAO5E,OAHI,MAD2B,EAA4B,CAAM,KAI1D;AACT"}
@@ -0,0 +1,2 @@
1
+ const e=require("../_virtual/_rolldown/runtime.cjs.js");let t=require("@uvdsl/solid-oidc-client-browser"),n=require("@uvdsl/solid-oidc-client-browser/core");n=e.__toESM(n);var r=class{constructor(){this.map=new Map}shouldPreserveExistingRefreshToken(e,t){return e===`refresh_token`&&(t==null||t===``)&&this.map.has(e)}async init(){return this}async setItem(e,t){this.shouldPreserveExistingRefreshToken(e,t)||this.map.set(e,t)}async getItem(e){return this.map.has(e)?this.map.get(e):null}async deleteItem(e){this.map.delete(e)}async clear(){this.map.clear()}close(){}},i=class{constructor(){this.db=null,this.dbName=`soidc`,this.storeName=`session`,this.dbVersion=1}async shouldPreserveExistingRefreshToken(e,t){if(e!==`refresh_token`||!(t==null||t===``))return!1;let n=await this.getItem(e);return n!=null&&n!==``}async init(){if(this.db)return this;if(typeof indexedDB>`u`)throw Error(`IndexedDB is not available in this environment`);return await new Promise((e,t)=>{let n=indexedDB.open(this.dbName,this.dbVersion);n.onerror=()=>t(n.error),n.onsuccess=()=>{this.db=n.result,e()},n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(this.storeName)||e.createObjectStore(this.storeName)}}),this}async setItem(e,t){await this.init(),!await this.shouldPreserveExistingRefreshToken(e,t)&&await this.withStore(`readwrite`,n=>n.put(t,e))}async getItem(e){return await this.init(),this.withStore(`readonly`,t=>t.get(e))}async deleteItem(e){await this.init(),await this.withStore(`readwrite`,t=>t.delete(e))}async clear(){await this.init(),await this.withStore(`readwrite`,e=>e.clear())}close(){this.db&&=(this.db.close(),null)}withStore(e,t){return new Promise((n,r)=>{if(!this.db){r(Error(`Session database not initialized`));return}let i=this.db.transaction(this.storeName,e),a=t(i.objectStore(this.storeName)),o=null;i.onerror=()=>r(i.error??a.error),i.onabort=()=>r(i.error??a.error??Error(`IndexedDB transaction aborted`)),i.oncomplete=()=>n(o),a.onerror=()=>r(a.error),a.onsuccess=()=>{o=a.result??null}})}};function a(){let e=n,t=e.SessionCore??e.default?.SessionCore??e.default;return typeof t==`function`?t:null}var o=a();function s(){if(typeof window<`u`&&(()=>{let e=window.location.hostname;return e===`localhost`||e===`127.0.0.1`||e.endsWith(`.localhost`)})())return o?new o(void 0,{database:new i}):new t.Session;try{return new t.Session}catch(e){console.warn(`solid-logic: falling back to non-worker auth session:`,e);try{return o?new o(void 0,{database:new i}):new t.Session}catch(e){return console.warn(`solid-logic: IndexedDB unavailable, using in-memory session database:`,e),o?new o(void 0,{database:new r}):new t.Session}}}var c=s();exports.IndexedDbSessionDatabase=i,exports.MemorySessionDatabase=r,exports._session=c;
2
+ //# sourceMappingURL=session.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.cjs.js","names":[],"sources":["../../src/authSession/session.ts"],"sourcesContent":["/**\n * OIDC session factory.\n *\n * Everything needed to create and configure the underlying auth session:\n * - Session database backends (in-memory and IndexedDB)\n * - Session instantiation (WebSession or SessionCore, with local-dev\n * fallbacks for environments where the service worker can't load)\n * - Login compatibility shim that normalises legacy call-site signatures\n * and resolves the canonical issuer through /.well-known discovery\n *\n * The raw session instance (_session) is consumed by authSession.ts where\n * the legacy event layer and logout listener are attached.\n *\n * DO NOT import _session directly — always go through authSession.ts so\n * the event wiring is guaranteed to run.\n */\n\nimport {\n Session as WebSession,\n} from '@uvdsl/solid-oidc-client-browser'\nimport * as OidcCore from '@uvdsl/solid-oidc-client-browser/core'\nimport type { Session as OidcSession, SessionDatabase } from '@uvdsl/solid-oidc-client-browser/core'\n\n// ---------------------------------------------------------------------------\n// Session databases\n// ---------------------------------------------------------------------------\n\nexport class MemorySessionDatabase implements SessionDatabase {\n private readonly map = new Map<string, any>()\n\n private shouldPreserveExistingRefreshToken(id: string, value: any): boolean {\n return id === 'refresh_token' && (value == null || value === '') && this.map.has(id)\n }\n\n async init (): Promise<SessionDatabase> {\n return this\n }\n\n async setItem (id: string, value: any): Promise<void> {\n // Some Solid IdPs do not include refresh_token on refresh responses.\n // Keep the previous token instead of overwriting it with null/undefined.\n if (this.shouldPreserveExistingRefreshToken(id, value)) {\n return\n }\n this.map.set(id, value)\n }\n\n async getItem (id: string): Promise<any> {\n return this.map.has(id) ? this.map.get(id) : null\n }\n\n async deleteItem (id: string): Promise<void> {\n this.map.delete(id)\n }\n\n async clear (): Promise<void> {\n this.map.clear()\n }\n\n close (): void {\n // No-op for in-memory database\n }\n}\n\nexport class IndexedDbSessionDatabase implements SessionDatabase {\n private db: IDBDatabase | null = null\n private readonly dbName = 'soidc'\n private readonly storeName = 'session'\n private readonly dbVersion = 1\n\n private async shouldPreserveExistingRefreshToken(id: string, value: any): Promise<boolean> {\n if (id !== 'refresh_token' || !(value == null || value === '')) {\n return false\n }\n const existing = await this.getItem(id)\n return existing != null && existing !== ''\n }\n\n async init (): Promise<SessionDatabase> {\n if (this.db) return this\n if (typeof indexedDB === 'undefined') {\n throw new Error('IndexedDB is not available in this environment')\n }\n\n await new Promise<void>((resolve, reject) => {\n const request = indexedDB.open(this.dbName, this.dbVersion)\n\n request.onerror = () => reject(request.error)\n request.onsuccess = () => {\n this.db = request.result\n resolve()\n }\n request.onupgradeneeded = () => {\n const db = request.result\n if (!db.objectStoreNames.contains(this.storeName)) {\n db.createObjectStore(this.storeName)\n }\n }\n })\n\n return this\n }\n\n async setItem (id: string, value: any): Promise<void> {\n await this.init()\n // Some Solid IdPs do not include refresh_token on refresh responses.\n // Keep the previous token instead of overwriting it with null/undefined.\n if (await this.shouldPreserveExistingRefreshToken(id, value)) {\n return\n }\n await this.withStore('readwrite', store => store.put(value, id))\n }\n\n async getItem (id: string): Promise<any> {\n await this.init()\n return this.withStore('readonly', store => store.get(id))\n }\n\n async deleteItem (id: string): Promise<void> {\n await this.init()\n await this.withStore('readwrite', store => store.delete(id))\n }\n\n async clear (): Promise<void> {\n await this.init()\n await this.withStore('readwrite', store => store.clear())\n }\n\n close (): void {\n if (this.db) {\n this.db.close()\n this.db = null\n }\n }\n\n private withStore(mode: IDBTransactionMode, op: (store: IDBObjectStore) => IDBRequest<any>): Promise<any> {\n return new Promise<any>((resolve, reject) => {\n if (!this.db) {\n reject(new Error('Session database not initialized'))\n return\n }\n\n const tx = this.db.transaction(this.storeName, mode)\n const store = tx.objectStore(this.storeName)\n const request = op(store)\n let result: any = null\n\n tx.onerror = () => reject(tx.error ?? request.error)\n tx.onabort = () => reject(tx.error ?? request.error ?? new Error('IndexedDB transaction aborted'))\n tx.oncomplete = () => resolve(result)\n\n request.onerror = () => reject(request.error)\n request.onsuccess = () => {\n result = request.result ?? null\n }\n })\n }\n}\n\n// ---------------------------------------------------------------------------\n// Session instantiation\n// ---------------------------------------------------------------------------\n\nfunction getSessionCoreCtor (): (new (...args: any[]) => OidcSession) | null {\n const coreAny = OidcCore as any\n const candidate = coreAny.SessionCore ?? coreAny.default?.SessionCore ?? coreAny.default\n\n if (typeof candidate !== 'function') {\n return null\n }\n\n return candidate as new (...args: any[]) => OidcSession\n}\n\nconst SessionCoreCtor = getSessionCoreCtor()\n\nfunction createSession (): OidcSession {\n const shouldSkipWorkerInLocalDev = typeof window !== 'undefined' && (() => {\n const host = window.location.hostname\n // In local NSS setups (including subdomain mode like alice.localhost),\n // worker-based session storage can be brittle and lose state on reload.\n // Prefer SessionCore + IndexedDB for deterministic persistence.\n return host === 'localhost' || host === '127.0.0.1' || host.endsWith('.localhost')\n })()\n\n if (shouldSkipWorkerInLocalDev) {\n if (SessionCoreCtor) {\n return new SessionCoreCtor(undefined, { database: new IndexedDbSessionDatabase() })\n }\n return new WebSession()\n }\n\n try {\n return new WebSession()\n } catch (error) {\n // In some deployments, worker URL resolution can become file:// and fail cross-origin.\n // Fall back to SessionCore so auth still works without background refresh worker.\n // Use IndexedDB to keep refresh-token persistence across page reloads.\n console.warn('solid-logic: falling back to non-worker auth session:', error)\n try {\n if (SessionCoreCtor) {\n return new SessionCoreCtor(undefined, { database: new IndexedDbSessionDatabase() })\n }\n return new WebSession()\n } catch (dbError) {\n console.warn('solid-logic: IndexedDB unavailable, using in-memory session database:', dbError)\n if (SessionCoreCtor) {\n return new SessionCoreCtor(undefined, { database: new MemorySessionDatabase() })\n }\n return new WebSession()\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Singleton session\n// ---------------------------------------------------------------------------\n\nconst _session = createSession()\n\nexport { _session }\n"],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ import { Session as e } from "@uvdsl/solid-oidc-client-browser";
2
+ import * as t from "@uvdsl/solid-oidc-client-browser/core";
3
+ //#region src/authSession/session.ts
4
+ var n = class {
5
+ constructor() {
6
+ this.map = /* @__PURE__ */ new Map();
7
+ }
8
+ shouldPreserveExistingRefreshToken(e, t) {
9
+ return e === "refresh_token" && (t == null || t === "") && this.map.has(e);
10
+ }
11
+ async init() {
12
+ return this;
13
+ }
14
+ async setItem(e, t) {
15
+ this.shouldPreserveExistingRefreshToken(e, t) || this.map.set(e, t);
16
+ }
17
+ async getItem(e) {
18
+ return this.map.has(e) ? this.map.get(e) : null;
19
+ }
20
+ async deleteItem(e) {
21
+ this.map.delete(e);
22
+ }
23
+ async clear() {
24
+ this.map.clear();
25
+ }
26
+ close() {}
27
+ }, r = class {
28
+ constructor() {
29
+ this.db = null, this.dbName = "soidc", this.storeName = "session", this.dbVersion = 1;
30
+ }
31
+ async shouldPreserveExistingRefreshToken(e, t) {
32
+ if (e !== "refresh_token" || !(t == null || t === "")) return !1;
33
+ let n = await this.getItem(e);
34
+ return n != null && n !== "";
35
+ }
36
+ async init() {
37
+ if (this.db) return this;
38
+ if (typeof indexedDB > "u") throw Error("IndexedDB is not available in this environment");
39
+ return await new Promise((e, t) => {
40
+ let n = indexedDB.open(this.dbName, this.dbVersion);
41
+ n.onerror = () => t(n.error), n.onsuccess = () => {
42
+ this.db = n.result, e();
43
+ }, n.onupgradeneeded = () => {
44
+ let e = n.result;
45
+ e.objectStoreNames.contains(this.storeName) || e.createObjectStore(this.storeName);
46
+ };
47
+ }), this;
48
+ }
49
+ async setItem(e, t) {
50
+ await this.init(), !await this.shouldPreserveExistingRefreshToken(e, t) && await this.withStore("readwrite", (n) => n.put(t, e));
51
+ }
52
+ async getItem(e) {
53
+ return await this.init(), this.withStore("readonly", (t) => t.get(e));
54
+ }
55
+ async deleteItem(e) {
56
+ await this.init(), await this.withStore("readwrite", (t) => t.delete(e));
57
+ }
58
+ async clear() {
59
+ await this.init(), await this.withStore("readwrite", (e) => e.clear());
60
+ }
61
+ close() {
62
+ this.db &&= (this.db.close(), null);
63
+ }
64
+ withStore(e, t) {
65
+ return new Promise((n, r) => {
66
+ if (!this.db) {
67
+ r(/* @__PURE__ */ Error("Session database not initialized"));
68
+ return;
69
+ }
70
+ let i = this.db.transaction(this.storeName, e), a = t(i.objectStore(this.storeName)), o = null;
71
+ i.onerror = () => r(i.error ?? a.error), i.onabort = () => r(i.error ?? a.error ?? /* @__PURE__ */ Error("IndexedDB transaction aborted")), i.oncomplete = () => n(o), a.onerror = () => r(a.error), a.onsuccess = () => {
72
+ o = a.result ?? null;
73
+ };
74
+ });
75
+ }
76
+ };
77
+ function i() {
78
+ let e = t, n = e.SessionCore ?? e.default?.SessionCore ?? e.default;
79
+ return typeof n == "function" ? n : null;
80
+ }
81
+ var a = i();
82
+ function o() {
83
+ if (typeof window < "u" && (() => {
84
+ let e = window.location.hostname;
85
+ return e === "localhost" || e === "127.0.0.1" || e.endsWith(".localhost");
86
+ })()) return a ? new a(void 0, { database: new r() }) : new e();
87
+ try {
88
+ return new e();
89
+ } catch (t) {
90
+ console.warn("solid-logic: falling back to non-worker auth session:", t);
91
+ try {
92
+ return a ? new a(void 0, { database: new r() }) : new e();
93
+ } catch (t) {
94
+ return console.warn("solid-logic: IndexedDB unavailable, using in-memory session database:", t), a ? new a(void 0, { database: new n() }) : new e();
95
+ }
96
+ }
97
+ }
98
+ var s = o();
99
+ //#endregion
100
+ export { r as IndexedDbSessionDatabase, n as MemorySessionDatabase, s as _session };
101
+
102
+ //# sourceMappingURL=session.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.esm.js","names":[],"sources":["../../src/authSession/session.ts"],"sourcesContent":["/**\n * OIDC session factory.\n *\n * Everything needed to create and configure the underlying auth session:\n * - Session database backends (in-memory and IndexedDB)\n * - Session instantiation (WebSession or SessionCore, with local-dev\n * fallbacks for environments where the service worker can't load)\n * - Login compatibility shim that normalises legacy call-site signatures\n * and resolves the canonical issuer through /.well-known discovery\n *\n * The raw session instance (_session) is consumed by authSession.ts where\n * the legacy event layer and logout listener are attached.\n *\n * DO NOT import _session directly — always go through authSession.ts so\n * the event wiring is guaranteed to run.\n */\n\nimport {\n Session as WebSession,\n} from '@uvdsl/solid-oidc-client-browser'\nimport * as OidcCore from '@uvdsl/solid-oidc-client-browser/core'\nimport type { Session as OidcSession, SessionDatabase } from '@uvdsl/solid-oidc-client-browser/core'\n\n// ---------------------------------------------------------------------------\n// Session databases\n// ---------------------------------------------------------------------------\n\nexport class MemorySessionDatabase implements SessionDatabase {\n private readonly map = new Map<string, any>()\n\n private shouldPreserveExistingRefreshToken(id: string, value: any): boolean {\n return id === 'refresh_token' && (value == null || value === '') && this.map.has(id)\n }\n\n async init (): Promise<SessionDatabase> {\n return this\n }\n\n async setItem (id: string, value: any): Promise<void> {\n // Some Solid IdPs do not include refresh_token on refresh responses.\n // Keep the previous token instead of overwriting it with null/undefined.\n if (this.shouldPreserveExistingRefreshToken(id, value)) {\n return\n }\n this.map.set(id, value)\n }\n\n async getItem (id: string): Promise<any> {\n return this.map.has(id) ? this.map.get(id) : null\n }\n\n async deleteItem (id: string): Promise<void> {\n this.map.delete(id)\n }\n\n async clear (): Promise<void> {\n this.map.clear()\n }\n\n close (): void {\n // No-op for in-memory database\n }\n}\n\nexport class IndexedDbSessionDatabase implements SessionDatabase {\n private db: IDBDatabase | null = null\n private readonly dbName = 'soidc'\n private readonly storeName = 'session'\n private readonly dbVersion = 1\n\n private async shouldPreserveExistingRefreshToken(id: string, value: any): Promise<boolean> {\n if (id !== 'refresh_token' || !(value == null || value === '')) {\n return false\n }\n const existing = await this.getItem(id)\n return existing != null && existing !== ''\n }\n\n async init (): Promise<SessionDatabase> {\n if (this.db) return this\n if (typeof indexedDB === 'undefined') {\n throw new Error('IndexedDB is not available in this environment')\n }\n\n await new Promise<void>((resolve, reject) => {\n const request = indexedDB.open(this.dbName, this.dbVersion)\n\n request.onerror = () => reject(request.error)\n request.onsuccess = () => {\n this.db = request.result\n resolve()\n }\n request.onupgradeneeded = () => {\n const db = request.result\n if (!db.objectStoreNames.contains(this.storeName)) {\n db.createObjectStore(this.storeName)\n }\n }\n })\n\n return this\n }\n\n async setItem (id: string, value: any): Promise<void> {\n await this.init()\n // Some Solid IdPs do not include refresh_token on refresh responses.\n // Keep the previous token instead of overwriting it with null/undefined.\n if (await this.shouldPreserveExistingRefreshToken(id, value)) {\n return\n }\n await this.withStore('readwrite', store => store.put(value, id))\n }\n\n async getItem (id: string): Promise<any> {\n await this.init()\n return this.withStore('readonly', store => store.get(id))\n }\n\n async deleteItem (id: string): Promise<void> {\n await this.init()\n await this.withStore('readwrite', store => store.delete(id))\n }\n\n async clear (): Promise<void> {\n await this.init()\n await this.withStore('readwrite', store => store.clear())\n }\n\n close (): void {\n if (this.db) {\n this.db.close()\n this.db = null\n }\n }\n\n private withStore(mode: IDBTransactionMode, op: (store: IDBObjectStore) => IDBRequest<any>): Promise<any> {\n return new Promise<any>((resolve, reject) => {\n if (!this.db) {\n reject(new Error('Session database not initialized'))\n return\n }\n\n const tx = this.db.transaction(this.storeName, mode)\n const store = tx.objectStore(this.storeName)\n const request = op(store)\n let result: any = null\n\n tx.onerror = () => reject(tx.error ?? request.error)\n tx.onabort = () => reject(tx.error ?? request.error ?? new Error('IndexedDB transaction aborted'))\n tx.oncomplete = () => resolve(result)\n\n request.onerror = () => reject(request.error)\n request.onsuccess = () => {\n result = request.result ?? null\n }\n })\n }\n}\n\n// ---------------------------------------------------------------------------\n// Session instantiation\n// ---------------------------------------------------------------------------\n\nfunction getSessionCoreCtor (): (new (...args: any[]) => OidcSession) | null {\n const coreAny = OidcCore as any\n const candidate = coreAny.SessionCore ?? coreAny.default?.SessionCore ?? coreAny.default\n\n if (typeof candidate !== 'function') {\n return null\n }\n\n return candidate as new (...args: any[]) => OidcSession\n}\n\nconst SessionCoreCtor = getSessionCoreCtor()\n\nfunction createSession (): OidcSession {\n const shouldSkipWorkerInLocalDev = typeof window !== 'undefined' && (() => {\n const host = window.location.hostname\n // In local NSS setups (including subdomain mode like alice.localhost),\n // worker-based session storage can be brittle and lose state on reload.\n // Prefer SessionCore + IndexedDB for deterministic persistence.\n return host === 'localhost' || host === '127.0.0.1' || host.endsWith('.localhost')\n })()\n\n if (shouldSkipWorkerInLocalDev) {\n if (SessionCoreCtor) {\n return new SessionCoreCtor(undefined, { database: new IndexedDbSessionDatabase() })\n }\n return new WebSession()\n }\n\n try {\n return new WebSession()\n } catch (error) {\n // In some deployments, worker URL resolution can become file:// and fail cross-origin.\n // Fall back to SessionCore so auth still works without background refresh worker.\n // Use IndexedDB to keep refresh-token persistence across page reloads.\n console.warn('solid-logic: falling back to non-worker auth session:', error)\n try {\n if (SessionCoreCtor) {\n return new SessionCoreCtor(undefined, { database: new IndexedDbSessionDatabase() })\n }\n return new WebSession()\n } catch (dbError) {\n console.warn('solid-logic: IndexedDB unavailable, using in-memory session database:', dbError)\n if (SessionCoreCtor) {\n return new SessionCoreCtor(undefined, { database: new MemorySessionDatabase() })\n }\n return new WebSession()\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Singleton session\n// ---------------------------------------------------------------------------\n\nconst _session = createSession()\n\nexport { _session }\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require("../util/debug.cjs.js"),t=require("./authUtil.cjs.js");let n=require("rdflib");var r=class{constructor(e){this.checkUserInFlight=null,this.sessionRestoreHookAttached=!1,this.fallbackWebId=null,this.session=e}get authSession(){return this.session}currentUser(){let e=t.appContext();if(e.viewingNoAuthPage)return(0,n.sym)(e.webId);let r=this.session,i=r?.info?.webId,a=r?.webId,o=i||a||this.fallbackWebId,s=r?.info?.isLoggedIn,c=r?.isActive,l=s===!0||c===!0||(s==null&&c==null?!!o:!1)||!!this.fallbackWebId;return this&&this.session&&o&&l?(0,n.sym)(o):t.offlineTestID()}async checkUser(t){let n=new URL(window.location.href).hash;n&&window.localStorage.setItem(`preLoginRedirectHash`,n);let r=this.session;!this.sessionRestoreHookAttached&&typeof r?.events?.on==`function`&&(r.events.on(`sessionRestore`,t=>{e.log(`Session restored to ${t}`),document.location.toString()!==t&&history.replaceState(null,``,t)}),this.sessionRestoreHookAttached=!0),this.checkUserInFlight||=this.resolveCurrentUser();let i=this.checkUserInFlight,a;try{a=await i}finally{this.checkUserInFlight===i&&(this.checkUserInFlight=null)}return Promise.resolve(t?t(a):a)}async resolveCurrentUser(){let n=this.session,r=new URL(window.location.href);if(r.hash=``,typeof n?.handleIncomingRedirect==`function`)await n.handleIncomingRedirect({restorePreviousSession:!0,url:r.href});else{if(typeof n?.restore==`function`){let t=n?.isActive??!!n?.webId;try{await n.restore()}catch(t){let n=t instanceof Error?t.message:String(t);if(!/no session to restore/i.test(n))throw t;e.log(`No previous session to restore`)}let r=n?.isActive??!!n?.webId;!t&&r&&n.events?.emit(`sessionRestore`,window.location.href)}if(typeof n?.handleRedirectFromLogin==`function`){let e=n?.isActive??!!n?.webId;await n.handleRedirectFromLogin();let t=n?.isActive??!!n?.webId;!e&&t&&n.events?.emit(`login`)}}let i=window.localStorage.getItem(`preLoginRedirectHash`);if(i){let e=new URL(window.location.href);e.hash!==i&&(history.pushState?history.pushState(null,document.title,i):location.hash=i,e.hash=i),window.localStorage.setItem(`preLoginRedirectHash`,``)}let a=t.offlineTestID();if(a)return a;let o=this.webIdFromSession(n?.info,n);return o||=await this.probeNssCookieBackedWebId(),o?this.fallbackWebId=o:this.fallbackWebId=null,o&&(a=this.saveUser(o)),a&&e.log(`(Logged in as ${a} by authentication)`),a}async probeNssCookieBackedWebId(){if(typeof window>`u`)return null;let{hostname:e,port:t,protocol:n}=window.location;if(!e.endsWith(`.localhost`))return null;let r=e.slice(0,-10);if(!r||r===`localhost`||r.includes(`.`))return null;try{return(await fetch(`/account/password/change`,{credentials:`include`,redirect:`manual`,cache:`no-store`})).status===403?`${`${n}//${e}${t?`:${t}`:``}`}/profile/card#me`:null}catch{return null}}saveUser(e,t){let r;if(e){r=typeof e==`string`?e:e.uri;let i=(0,n.namedNode)(r);return t&&(t.me=i),i}return null}webIdFromSession(e,t){let n=e?.webId||t?.webId;if(!n)return null;let r=e?.isLoggedIn,i=t?.isLoggedIn,a=t?.isActive;return r===!0||i===!0||a===!0?n:r===!1&&i===!1&&a===!1?null:n}};exports.SolidAuthnLogic=r;
2
+ //# sourceMappingURL=SolidAuthnLogic.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SolidAuthnLogic.cjs.js","names":[],"sources":["../../src/authn/SolidAuthnLogic.ts"],"sourcesContent":["import { namedNode, NamedNode, sym } from 'rdflib'\nimport { appContext, offlineTestID } from './authUtil'\nimport * as debug from '../util/debug'\nimport type { SessionWithLegacyEvents } from '../authSession/authSession'\nimport type { AuthenticationContext, AuthnLogic } from '../types'\n\nexport class SolidAuthnLogic implements AuthnLogic {\n private session: SessionWithLegacyEvents\n private checkUserInFlight: Promise<NamedNode | null> | null = null\n private sessionRestoreHookAttached = false\n private fallbackWebId: string | null = null\n\n constructor(solidAuthSession: SessionWithLegacyEvents) {\n this.session = solidAuthSession\n }\n\n // we created authSession getter because we want to access it as authn.authSession externally\n get authSession(): SessionWithLegacyEvents { return this.session }\n\n currentUser(): NamedNode | null {\n const app = appContext()\n if (app.viewingNoAuthPage) {\n return sym(app.webId)\n }\n const sessionAny = this.session as any\n const infoWebId = sessionAny?.info?.webId\n const sessionWebId = sessionAny?.webId\n const webId = infoWebId || sessionWebId || this.fallbackWebId\n const infoLoggedIn = sessionAny?.info?.isLoggedIn\n const sessionActive = sessionAny?.isActive\n const isLoggedIn = infoLoggedIn === true || sessionActive === true ||\n ((infoLoggedIn == null && sessionActive == null) ? Boolean(webId) : false) ||\n Boolean(this.fallbackWebId)\n if (this && this.session && webId && isLoggedIn) {\n return sym(webId)\n }\n return offlineTestID() // null unless testing\n }\n\n /**\n * Retrieves currently logged in webId from either\n * defaultTestUser or SolidAuth\n * Also activates a session after login\n * @param [setUserCallback] Optional callback\n * @returns Resolves with webId uri, if no callback provided\n */\n async checkUser<T> (\n setUserCallback?: (me: NamedNode | null) => T\n ): Promise<NamedNode | T | null> {\n // Save hash for \"restorePreviousSession\"\n const preLoginRedirectHash = new URL(window.location.href).hash\n if (preLoginRedirectHash) {\n window.localStorage.setItem('preLoginRedirectHash', preLoginRedirectHash)\n }\n const sessionAny = this.session as any\n if (!this.sessionRestoreHookAttached && typeof sessionAny?.events?.on === 'function') {\n // Backward-compatible hook for auth clients exposing an EventEmitter-style API.\n sessionAny.events.on('sessionRestore', (url: string) => {\n debug.log(`Session restored to ${url}`)\n if (document.location.toString() !== url) history.replaceState(null, '', url)\n })\n this.sessionRestoreHookAttached = true\n }\n\n if (!this.checkUserInFlight) {\n this.checkUserInFlight = this.resolveCurrentUser()\n }\n\n const inFlight = this.checkUserInFlight\n let me: NamedNode | null\n try {\n me = await inFlight\n } finally {\n if (this.checkUserInFlight === inFlight) {\n this.checkUserInFlight = null\n }\n }\n\n return Promise.resolve(setUserCallback ? setUserCallback(me) : me)\n }\n\n private async resolveCurrentUser (): Promise<NamedNode | null> {\n const sessionAny = this.session as any\n\n /**\n * Handle a successful authentication redirect\n */\n const redirectUrl = new URL(window.location.href)\n redirectUrl.hash = ''\n if (typeof sessionAny?.handleIncomingRedirect === 'function') {\n await sessionAny.handleIncomingRedirect({\n restorePreviousSession: true,\n url: redirectUrl.href\n })\n } else {\n if (typeof sessionAny?.restore === 'function') {\n const wasActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n try {\n await sessionAny.restore()\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n if (!/no session to restore/i.test(message)) {\n throw error\n }\n debug.log('No previous session to restore')\n }\n const isNowActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n if (!wasActive && isNowActive) {\n sessionAny.events?.emit('sessionRestore', window.location.href)\n }\n }\n if (typeof sessionAny?.handleRedirectFromLogin === 'function') {\n const wasActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n await sessionAny.handleRedirectFromLogin()\n const isNowActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n if (!wasActive && isNowActive) {\n sessionAny.events?.emit('login')\n }\n }\n }\n\n // Check to see if a hash was stored in local storage\n const postLoginRedirectHash = window.localStorage.getItem('preLoginRedirectHash')\n if (postLoginRedirectHash) {\n const curUrl = new URL(window.location.href)\n if (curUrl.hash !== postLoginRedirectHash) {\n if (history.pushState) {\n // debug.log('Setting window.location.has using pushState')\n history.pushState(null, document.title, postLoginRedirectHash)\n } else {\n // debug.warn('Setting window.location.has using location.hash')\n location.hash = postLoginRedirectHash\n }\n curUrl.hash = postLoginRedirectHash\n }\n // See https://stackoverflow.com/questions/3870057/how-can-i-update-window-location-hash-without-jumping-the-document\n // window.location.href = curUrl.toString()// @@ See https://developer.mozilla.org/en-US/docs/Web/API/Window/location\n window.localStorage.setItem('preLoginRedirectHash', '')\n }\n\n // Check to see if already logged in / have the WebID\n let me = offlineTestID()\n if (me) {\n return me\n }\n\n let webId = this.webIdFromSession(sessionAny?.info, sessionAny)\n if (!webId) {\n // NSS-specific fallback: recover WebID from NSS cookie session when client restore is empty.\n webId = await this.probeNssCookieBackedWebId()\n }\n\n if (webId) {\n this.fallbackWebId = webId\n } else {\n this.fallbackWebId = null\n }\n\n if (webId) {\n me = this.saveUser(webId)\n }\n\n if (me) {\n debug.log(`(Logged in as ${me} by authentication)`)\n }\n\n return me\n }\n\n private async probeNssCookieBackedWebId (): Promise<string | null> {\n if (typeof window === 'undefined') {\n return null\n }\n\n const { hostname, port, protocol } = window.location\n const localhostSuffix = '.localhost'\n // NSS local pods use subdomains like alice.localhost.\n if (!hostname.endsWith(localhostSuffix)) {\n return null\n }\n\n const podName = hostname.slice(0, -localhostSuffix.length)\n if (!podName || podName === 'localhost' || podName.includes('.')) {\n return null\n }\n\n try {\n // NSS returns 403 on this account page when the cookie session is valid.\n const probeResponse = await fetch('/account/password/change', {\n credentials: 'include',\n redirect: 'manual',\n cache: 'no-store'\n })\n if (probeResponse.status !== 403) {\n return null\n }\n const origin = `${protocol}//${hostname}${port ? `:${port}` : ''}`\n return `${origin}/profile/card#me`\n } catch (_error) {\n return null\n }\n }\n\n /**\n * Saves `webId` in `context.me`\n * @param webId\n * @param context\n *\n * @returns Returns the WebID, after setting it\n */\n saveUser (\n webId: NamedNode | string | null,\n context?: AuthenticationContext\n ): NamedNode | null {\n let webIdUri: string\n if (webId) {\n webIdUri = (typeof webId === 'string') ? webId : webId.uri\n const me = namedNode(webIdUri)\n if (context) {\n context.me = me\n }\n return me\n }\n return null\n }\n\n /**\n * @returns {Promise<string|null>} Resolves with WebID URI or null\n */\n webIdFromSession (\n sessionInfo?: { webId?: string, isLoggedIn?: boolean },\n sessionRoot?: { webId?: string, isLoggedIn?: boolean, isActive?: boolean }\n ): string | null {\n const webId = sessionInfo?.webId || sessionRoot?.webId\n if (!webId) {\n return null\n }\n const infoLoggedIn = sessionInfo?.isLoggedIn\n const rootLoggedIn = sessionRoot?.isLoggedIn\n const rootActive = sessionRoot?.isActive\n if (infoLoggedIn === true || rootLoggedIn === true || rootActive === true) {\n return webId\n }\n if (infoLoggedIn === false && rootLoggedIn === false && rootActive === false) {\n return null\n }\n return webId\n }\n\n}\n"],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ import { log as e } from "../util/debug.esm.js";
2
+ import { appContext as t, offlineTestID as n } from "./authUtil.esm.js";
3
+ import { namedNode as r, sym as i } from "rdflib";
4
+ //#region src/authn/SolidAuthnLogic.ts
5
+ var a = class {
6
+ constructor(e) {
7
+ this.checkUserInFlight = null, this.sessionRestoreHookAttached = !1, this.fallbackWebId = null, this.session = e;
8
+ }
9
+ get authSession() {
10
+ return this.session;
11
+ }
12
+ currentUser() {
13
+ let e = t();
14
+ if (e.viewingNoAuthPage) return i(e.webId);
15
+ let r = this.session, a = r?.info?.webId, o = r?.webId, s = a || o || this.fallbackWebId, c = r?.info?.isLoggedIn, l = r?.isActive, u = c === !0 || l === !0 || (c == null && l == null ? !!s : !1) || !!this.fallbackWebId;
16
+ return this && this.session && s && u ? i(s) : n();
17
+ }
18
+ async checkUser(t) {
19
+ let n = new URL(window.location.href).hash;
20
+ n && window.localStorage.setItem("preLoginRedirectHash", n);
21
+ let r = this.session;
22
+ !this.sessionRestoreHookAttached && typeof r?.events?.on == "function" && (r.events.on("sessionRestore", (t) => {
23
+ e(`Session restored to ${t}`), document.location.toString() !== t && history.replaceState(null, "", t);
24
+ }), this.sessionRestoreHookAttached = !0), this.checkUserInFlight ||= this.resolveCurrentUser();
25
+ let i = this.checkUserInFlight, a;
26
+ try {
27
+ a = await i;
28
+ } finally {
29
+ this.checkUserInFlight === i && (this.checkUserInFlight = null);
30
+ }
31
+ return Promise.resolve(t ? t(a) : a);
32
+ }
33
+ async resolveCurrentUser() {
34
+ let t = this.session, r = new URL(window.location.href);
35
+ if (r.hash = "", typeof t?.handleIncomingRedirect == "function") await t.handleIncomingRedirect({
36
+ restorePreviousSession: !0,
37
+ url: r.href
38
+ });
39
+ else {
40
+ if (typeof t?.restore == "function") {
41
+ let n = t?.isActive ?? !!t?.webId;
42
+ try {
43
+ await t.restore();
44
+ } catch (t) {
45
+ let n = t instanceof Error ? t.message : String(t);
46
+ if (!/no session to restore/i.test(n)) throw t;
47
+ e("No previous session to restore");
48
+ }
49
+ let r = t?.isActive ?? !!t?.webId;
50
+ !n && r && t.events?.emit("sessionRestore", window.location.href);
51
+ }
52
+ if (typeof t?.handleRedirectFromLogin == "function") {
53
+ let e = t?.isActive ?? !!t?.webId;
54
+ await t.handleRedirectFromLogin();
55
+ let n = t?.isActive ?? !!t?.webId;
56
+ !e && n && t.events?.emit("login");
57
+ }
58
+ }
59
+ let i = window.localStorage.getItem("preLoginRedirectHash");
60
+ if (i) {
61
+ let e = new URL(window.location.href);
62
+ e.hash !== i && (history.pushState ? history.pushState(null, document.title, i) : location.hash = i, e.hash = i), window.localStorage.setItem("preLoginRedirectHash", "");
63
+ }
64
+ let a = n();
65
+ if (a) return a;
66
+ let o = this.webIdFromSession(t?.info, t);
67
+ return o ||= await this.probeNssCookieBackedWebId(), o ? this.fallbackWebId = o : this.fallbackWebId = null, o && (a = this.saveUser(o)), a && e(`(Logged in as ${a} by authentication)`), a;
68
+ }
69
+ async probeNssCookieBackedWebId() {
70
+ if (typeof window > "u") return null;
71
+ let { hostname: e, port: t, protocol: n } = window.location;
72
+ if (!e.endsWith(".localhost")) return null;
73
+ let r = e.slice(0, -10);
74
+ if (!r || r === "localhost" || r.includes(".")) return null;
75
+ try {
76
+ return (await fetch("/account/password/change", {
77
+ credentials: "include",
78
+ redirect: "manual",
79
+ cache: "no-store"
80
+ })).status === 403 ? `${`${n}//${e}${t ? `:${t}` : ""}`}/profile/card#me` : null;
81
+ } catch {
82
+ return null;
83
+ }
84
+ }
85
+ saveUser(e, t) {
86
+ let n;
87
+ if (e) {
88
+ n = typeof e == "string" ? e : e.uri;
89
+ let i = r(n);
90
+ return t && (t.me = i), i;
91
+ }
92
+ return null;
93
+ }
94
+ webIdFromSession(e, t) {
95
+ let n = e?.webId || t?.webId;
96
+ if (!n) return null;
97
+ let r = e?.isLoggedIn, i = t?.isLoggedIn, a = t?.isActive;
98
+ return r === !0 || i === !0 || a === !0 ? n : r === !1 && i === !1 && a === !1 ? null : n;
99
+ }
100
+ };
101
+ //#endregion
102
+ export { a as SolidAuthnLogic };
103
+
104
+ //# sourceMappingURL=SolidAuthnLogic.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SolidAuthnLogic.esm.js","names":[],"sources":["../../src/authn/SolidAuthnLogic.ts"],"sourcesContent":["import { namedNode, NamedNode, sym } from 'rdflib'\nimport { appContext, offlineTestID } from './authUtil'\nimport * as debug from '../util/debug'\nimport type { SessionWithLegacyEvents } from '../authSession/authSession'\nimport type { AuthenticationContext, AuthnLogic } from '../types'\n\nexport class SolidAuthnLogic implements AuthnLogic {\n private session: SessionWithLegacyEvents\n private checkUserInFlight: Promise<NamedNode | null> | null = null\n private sessionRestoreHookAttached = false\n private fallbackWebId: string | null = null\n\n constructor(solidAuthSession: SessionWithLegacyEvents) {\n this.session = solidAuthSession\n }\n\n // we created authSession getter because we want to access it as authn.authSession externally\n get authSession(): SessionWithLegacyEvents { return this.session }\n\n currentUser(): NamedNode | null {\n const app = appContext()\n if (app.viewingNoAuthPage) {\n return sym(app.webId)\n }\n const sessionAny = this.session as any\n const infoWebId = sessionAny?.info?.webId\n const sessionWebId = sessionAny?.webId\n const webId = infoWebId || sessionWebId || this.fallbackWebId\n const infoLoggedIn = sessionAny?.info?.isLoggedIn\n const sessionActive = sessionAny?.isActive\n const isLoggedIn = infoLoggedIn === true || sessionActive === true ||\n ((infoLoggedIn == null && sessionActive == null) ? Boolean(webId) : false) ||\n Boolean(this.fallbackWebId)\n if (this && this.session && webId && isLoggedIn) {\n return sym(webId)\n }\n return offlineTestID() // null unless testing\n }\n\n /**\n * Retrieves currently logged in webId from either\n * defaultTestUser or SolidAuth\n * Also activates a session after login\n * @param [setUserCallback] Optional callback\n * @returns Resolves with webId uri, if no callback provided\n */\n async checkUser<T> (\n setUserCallback?: (me: NamedNode | null) => T\n ): Promise<NamedNode | T | null> {\n // Save hash for \"restorePreviousSession\"\n const preLoginRedirectHash = new URL(window.location.href).hash\n if (preLoginRedirectHash) {\n window.localStorage.setItem('preLoginRedirectHash', preLoginRedirectHash)\n }\n const sessionAny = this.session as any\n if (!this.sessionRestoreHookAttached && typeof sessionAny?.events?.on === 'function') {\n // Backward-compatible hook for auth clients exposing an EventEmitter-style API.\n sessionAny.events.on('sessionRestore', (url: string) => {\n debug.log(`Session restored to ${url}`)\n if (document.location.toString() !== url) history.replaceState(null, '', url)\n })\n this.sessionRestoreHookAttached = true\n }\n\n if (!this.checkUserInFlight) {\n this.checkUserInFlight = this.resolveCurrentUser()\n }\n\n const inFlight = this.checkUserInFlight\n let me: NamedNode | null\n try {\n me = await inFlight\n } finally {\n if (this.checkUserInFlight === inFlight) {\n this.checkUserInFlight = null\n }\n }\n\n return Promise.resolve(setUserCallback ? setUserCallback(me) : me)\n }\n\n private async resolveCurrentUser (): Promise<NamedNode | null> {\n const sessionAny = this.session as any\n\n /**\n * Handle a successful authentication redirect\n */\n const redirectUrl = new URL(window.location.href)\n redirectUrl.hash = ''\n if (typeof sessionAny?.handleIncomingRedirect === 'function') {\n await sessionAny.handleIncomingRedirect({\n restorePreviousSession: true,\n url: redirectUrl.href\n })\n } else {\n if (typeof sessionAny?.restore === 'function') {\n const wasActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n try {\n await sessionAny.restore()\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n if (!/no session to restore/i.test(message)) {\n throw error\n }\n debug.log('No previous session to restore')\n }\n const isNowActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n if (!wasActive && isNowActive) {\n sessionAny.events?.emit('sessionRestore', window.location.href)\n }\n }\n if (typeof sessionAny?.handleRedirectFromLogin === 'function') {\n const wasActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n await sessionAny.handleRedirectFromLogin()\n const isNowActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n if (!wasActive && isNowActive) {\n sessionAny.events?.emit('login')\n }\n }\n }\n\n // Check to see if a hash was stored in local storage\n const postLoginRedirectHash = window.localStorage.getItem('preLoginRedirectHash')\n if (postLoginRedirectHash) {\n const curUrl = new URL(window.location.href)\n if (curUrl.hash !== postLoginRedirectHash) {\n if (history.pushState) {\n // debug.log('Setting window.location.has using pushState')\n history.pushState(null, document.title, postLoginRedirectHash)\n } else {\n // debug.warn('Setting window.location.has using location.hash')\n location.hash = postLoginRedirectHash\n }\n curUrl.hash = postLoginRedirectHash\n }\n // See https://stackoverflow.com/questions/3870057/how-can-i-update-window-location-hash-without-jumping-the-document\n // window.location.href = curUrl.toString()// @@ See https://developer.mozilla.org/en-US/docs/Web/API/Window/location\n window.localStorage.setItem('preLoginRedirectHash', '')\n }\n\n // Check to see if already logged in / have the WebID\n let me = offlineTestID()\n if (me) {\n return me\n }\n\n let webId = this.webIdFromSession(sessionAny?.info, sessionAny)\n if (!webId) {\n // NSS-specific fallback: recover WebID from NSS cookie session when client restore is empty.\n webId = await this.probeNssCookieBackedWebId()\n }\n\n if (webId) {\n this.fallbackWebId = webId\n } else {\n this.fallbackWebId = null\n }\n\n if (webId) {\n me = this.saveUser(webId)\n }\n\n if (me) {\n debug.log(`(Logged in as ${me} by authentication)`)\n }\n\n return me\n }\n\n private async probeNssCookieBackedWebId (): Promise<string | null> {\n if (typeof window === 'undefined') {\n return null\n }\n\n const { hostname, port, protocol } = window.location\n const localhostSuffix = '.localhost'\n // NSS local pods use subdomains like alice.localhost.\n if (!hostname.endsWith(localhostSuffix)) {\n return null\n }\n\n const podName = hostname.slice(0, -localhostSuffix.length)\n if (!podName || podName === 'localhost' || podName.includes('.')) {\n return null\n }\n\n try {\n // NSS returns 403 on this account page when the cookie session is valid.\n const probeResponse = await fetch('/account/password/change', {\n credentials: 'include',\n redirect: 'manual',\n cache: 'no-store'\n })\n if (probeResponse.status !== 403) {\n return null\n }\n const origin = `${protocol}//${hostname}${port ? `:${port}` : ''}`\n return `${origin}/profile/card#me`\n } catch (_error) {\n return null\n }\n }\n\n /**\n * Saves `webId` in `context.me`\n * @param webId\n * @param context\n *\n * @returns Returns the WebID, after setting it\n */\n saveUser (\n webId: NamedNode | string | null,\n context?: AuthenticationContext\n ): NamedNode | null {\n let webIdUri: string\n if (webId) {\n webIdUri = (typeof webId === 'string') ? webId : webId.uri\n const me = namedNode(webIdUri)\n if (context) {\n context.me = me\n }\n return me\n }\n return null\n }\n\n /**\n * @returns {Promise<string|null>} Resolves with WebID URI or null\n */\n webIdFromSession (\n sessionInfo?: { webId?: string, isLoggedIn?: boolean },\n sessionRoot?: { webId?: string, isLoggedIn?: boolean, isActive?: boolean }\n ): string | null {\n const webId = sessionInfo?.webId || sessionRoot?.webId\n if (!webId) {\n return null\n }\n const infoLoggedIn = sessionInfo?.isLoggedIn\n const rootLoggedIn = sessionRoot?.isLoggedIn\n const rootActive = sessionRoot?.isActive\n if (infoLoggedIn === true || rootLoggedIn === true || rootActive === true) {\n return webId\n }\n if (infoLoggedIn === false && rootLoggedIn === false && rootActive === false) {\n return null\n }\n return webId\n }\n\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require("../util/debug.cjs.js");let t=require("rdflib");var n=()=>{let{SolidAppContext:e}=window;if(e||={},e.viewingNoAuthPage=!1,e.noAuth&&window.document&&window.document.location.href.startsWith(e.noAuth)){e.viewingNoAuthPage=!0;let t=new URLSearchParams(window.document.location.search);if(t){let n=e.viewedPage=t.get(`uri`)||null;if(n&&(n=decodeURI(n),!n.startsWith(e.noAuth))){let t=n.split(/\//);e.idp=t[0]+`//`+t[2],e.viewingNoAuthPage=!1}}}return e};function r(){let{$SolidTestEnvironment:n}=window;if(n!==void 0&&n.username)return e.log(`Assuming the user is `+n.username),(0,t.sym)(n.username);if(typeof document<`u`&&document.location&&(``+document.location).slice(0,16)===`http://localhost`){let n=document.getElementById(`appTarget`);if(!n)return null;let r=n.getAttribute(`testID`);return r?(e.log(`Assuming user is `+r),(0,t.sym)(r)):null}return null}exports.appContext=n,exports.offlineTestID=r;
2
+ //# sourceMappingURL=authUtil.cjs.js.map