solid-logic 6.0.1-3 → 6.0.1-4

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 (99) hide show
  1. package/dist/acl/accessControlSubjects.cjs.js +1 -1
  2. package/dist/acl/accessControlSubjects.cjs.js.map +1 -1
  3. package/dist/acl/accessControlSubjects.d.ts.map +1 -1
  4. package/dist/acl/accessControlSubjects.esm.js +38 -37
  5. package/dist/acl/accessControlSubjects.esm.js.map +1 -1
  6. package/dist/acl/aclLogic.cjs.js +1 -1
  7. package/dist/acl/aclLogic.cjs.js.map +1 -1
  8. package/dist/acl/aclLogic.esm.js +2 -6
  9. package/dist/acl/aclLogic.esm.js.map +1 -1
  10. package/dist/authSession/authSession.cjs.js.map +1 -1
  11. package/dist/authSession/authSession.esm.js.map +1 -1
  12. package/dist/authSession/events.cjs.js.map +1 -1
  13. package/dist/authSession/events.esm.js.map +1 -1
  14. package/dist/authSession/flagAuthorizationOnTransitions.cjs.js.map +1 -1
  15. package/dist/authSession/flagAuthorizationOnTransitions.esm.js.map +1 -1
  16. package/dist/authSession/identityState.cjs.js +1 -1
  17. package/dist/authSession/identityState.cjs.js.map +1 -1
  18. package/dist/authSession/identityState.esm.js +3 -17
  19. package/dist/authSession/identityState.esm.js.map +1 -1
  20. package/dist/authSession/issuer.cjs.js.map +1 -1
  21. package/dist/authSession/issuer.esm.js.map +1 -1
  22. package/dist/authSession/session.cjs.js.map +1 -1
  23. package/dist/authSession/session.esm.js.map +1 -1
  24. package/dist/authn/SolidAuthnLogic.cjs.js.map +1 -1
  25. package/dist/authn/SolidAuthnLogic.esm.js.map +1 -1
  26. package/dist/authn/authUtil.cjs.js.map +1 -1
  27. package/dist/authn/authUtil.esm.js.map +1 -1
  28. package/dist/authn/serverLogout.cjs.js.map +1 -1
  29. package/dist/authn/serverLogout.esm.js.map +1 -1
  30. package/dist/chat/chatLogic.cjs.js.map +1 -1
  31. package/dist/chat/chatLogic.esm.js.map +1 -1
  32. package/dist/directory/catalogDirectory.cjs.js.map +1 -1
  33. package/dist/directory/catalogDirectory.esm.js.map +1 -1
  34. package/dist/directory/contactsDirectory.cjs.js.map +1 -1
  35. package/dist/directory/contactsDirectory.esm.js.map +1 -1
  36. package/dist/directory/directoryHelpers.cjs.js.map +1 -1
  37. package/dist/directory/directoryHelpers.esm.js.map +1 -1
  38. package/dist/directory/directoryLogic.cjs.js.map +1 -1
  39. package/dist/directory/directoryLogic.esm.js.map +1 -1
  40. package/dist/directory/friendsDirectory.cjs.js.map +1 -1
  41. package/dist/directory/friendsDirectory.esm.js.map +1 -1
  42. package/dist/inbox/inboxLogic.cjs.js.map +1 -1
  43. package/dist/inbox/inboxLogic.esm.js.map +1 -1
  44. package/dist/index.cjs.js.map +1 -1
  45. package/dist/index.d.ts +1 -1
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.esm.js.map +1 -1
  48. package/dist/issuer/issuerLogic.cjs.js.map +1 -1
  49. package/dist/issuer/issuerLogic.esm.js.map +1 -1
  50. package/dist/logic/CustomError.cjs.js.map +1 -1
  51. package/dist/logic/CustomError.esm.js.map +1 -1
  52. package/dist/logic/solidLogic.cjs.js.map +1 -1
  53. package/dist/logic/solidLogic.esm.js.map +1 -1
  54. package/dist/logic/solidLogicSingleton.cjs.js +1 -1
  55. package/dist/logic/solidLogicSingleton.cjs.js.map +1 -1
  56. package/dist/logic/solidLogicSingleton.esm.js +1 -1
  57. package/dist/logic/solidLogicSingleton.esm.js.map +1 -1
  58. package/dist/profile/profileAclDocuments.cjs.js.map +1 -1
  59. package/dist/profile/profileAclDocuments.esm.js.map +1 -1
  60. package/dist/profile/profileDocuments.cjs.js.map +1 -1
  61. package/dist/profile/profileDocuments.esm.js.map +1 -1
  62. package/dist/profile/profileLogic.cjs.js.map +1 -1
  63. package/dist/profile/profileLogic.esm.js.map +1 -1
  64. package/dist/resource/resourceHttp.cjs.js.map +1 -1
  65. package/dist/resource/resourceHttp.esm.js.map +1 -1
  66. package/dist/resource/resourceLogic.cjs.js +1 -1
  67. package/dist/resource/resourceLogic.cjs.js.map +1 -1
  68. package/dist/resource/resourceLogic.d.ts.map +1 -1
  69. package/dist/resource/resourceLogic.esm.js +80 -34
  70. package/dist/resource/resourceLogic.esm.js.map +1 -1
  71. package/dist/resource/resourceMetadata.cjs.js +1 -1
  72. package/dist/resource/resourceMetadata.cjs.js.map +1 -1
  73. package/dist/resource/resourceMetadata.d.ts +2 -0
  74. package/dist/resource/resourceMetadata.d.ts.map +1 -1
  75. package/dist/resource/resourceMetadata.esm.js +6 -2
  76. package/dist/resource/resourceMetadata.esm.js.map +1 -1
  77. package/dist/typeIndex/typeIndexAclDocuments.cjs.js.map +1 -1
  78. package/dist/typeIndex/typeIndexAclDocuments.esm.js.map +1 -1
  79. package/dist/typeIndex/typeIndexDocuments.cjs.js.map +1 -1
  80. package/dist/typeIndex/typeIndexDocuments.esm.js.map +1 -1
  81. package/dist/typeIndex/typeIndexLogic.cjs.js +1 -1
  82. package/dist/typeIndex/typeIndexLogic.cjs.js.map +1 -1
  83. package/dist/typeIndex/typeIndexLogic.esm.js +5 -10
  84. package/dist/typeIndex/typeIndexLogic.esm.js.map +1 -1
  85. package/dist/types.d.ts +13 -0
  86. package/dist/types.d.ts.map +1 -1
  87. package/dist/util/containerLogic.cjs.js.map +1 -1
  88. package/dist/util/containerLogic.esm.js.map +1 -1
  89. package/dist/util/debug.cjs.js +1 -1
  90. package/dist/util/debug.cjs.js.map +1 -1
  91. package/dist/util/debug.esm.js +4 -1
  92. package/dist/util/debug.esm.js.map +1 -1
  93. package/dist/util/ns.cjs.js.map +1 -1
  94. package/dist/util/ns.esm.js.map +1 -1
  95. package/dist/util/utilityLogic.cjs.js.map +1 -1
  96. package/dist/util/utilityLogic.esm.js.map +1 -1
  97. package/dist/util/utils.cjs.js.map +1 -1
  98. package/dist/util/utils.esm.js.map +1 -1
  99. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- const e=require("../util/ns.cjs.js");let t=require("rdflib");var n={agentClass:[e.ns.foaf(`Agent`),e.ns.acl(`AuthenticatedAgent`),e.ns.rdf(`Resource`),e.ns.owl(`Thing`)],agent:[e.ns.vcard(`WebID`),e.ns.vcard(`Individual`),e.ns.foaf(`Person`),e.ns.foaf(`Agent`)],agentGroup:[e.ns.vcard(`Group`)],origin:[e.ns.solid(`AppProvider`),e.ns.solid(`AppProviderClass`)]};function r(e){return Object.keys(e).length>0}function i(e){return e.startsWith(`http://`)||e.startsWith(`https://`)}function a(e){try{let t=new URL(e);return(t.protocol===`http:`||t.protocol===`https:`)&&t.pathname===`/`&&!t.search&&!t.hash}catch{return!1}}function o(e){try{let t=new URL(e);if((t.protocol===`http:`||t.protocol===`https:`)&&t.pathname===`/`&&!t.search&&!t.hash)return`${t.protocol}//${t.host}`}catch{}return e}async function s(s,c){let l=(0,t.sym)(c),u=s.findTypeURIs(l);if(a(c))return{kind:`origin`,subjectValue:o(c)};if(!r(u)&&i(c)){try{await s.fetcher.load(l.doc())}catch(e){console.error(`Failed to load access target ${c}`,e)}u=s.findTypeURIs(l)}if(n.origin.some(e=>e.uri in u))return{kind:`origin`,subjectValue:c};if(n.agent.some(e=>e.uri in u))return{kind:`agent`,subjectValue:s.any(l,e.ns.foaf(`preferredURI`))?.value??c};if(n.agentGroup.some(e=>e.uri in u))return{kind:`agentGroup`,subjectValue:c};if(n.agentClass.some(e=>l.sameTerm(e)))return{kind:`agentClass`,subjectValue:c}}exports.classifyAccessControlSubject=s;
1
+ const e=require("../util/debug.cjs.js"),t=require("../util/ns.cjs.js");let n=require("rdflib");var r={agentClass:[t.ns.foaf(`Agent`),t.ns.acl(`AuthenticatedAgent`),t.ns.rdf(`Resource`),t.ns.owl(`Thing`)],agent:[t.ns.vcard(`WebID`),t.ns.vcard(`Individual`),t.ns.foaf(`Person`),t.ns.foaf(`Agent`)],agentGroup:[t.ns.vcard(`Group`)],origin:[t.ns.solid(`AppProvider`),t.ns.solid(`AppProviderClass`)]};function i(e){return Object.keys(e).length>0}function a(e){return e.startsWith(`http://`)||e.startsWith(`https://`)}function o(e){try{let t=new URL(e);return(t.protocol===`http:`||t.protocol===`https:`)&&!!t.hostname&&t.pathname===`/`&&!t.search&&!t.hash&&!t.username&&!t.password}catch{return!1}}function s(e){try{let t=new URL(e);if((t.protocol===`http:`||t.protocol===`https:`)&&t.hostname&&t.pathname===`/`&&!t.search&&!t.hash&&!t.username&&!t.password)return`${t.protocol}//${t.host}`}catch{}return e}async function c(c,l){let u=(0,n.sym)(l),d=c.findTypeURIs(u);if(o(l))return{kind:`origin`,subjectValue:s(l)};if(!i(d)&&a(l)){try{await c.fetcher.load(u.doc())}catch(t){e.error(`Failed to load access target ${l}`,t)}d=c.findTypeURIs(u)}if(r.origin.some(e=>e.uri in d))return{kind:`origin`,subjectValue:l};if(r.agent.some(e=>e.uri in d))return{kind:`agent`,subjectValue:c.any(u,t.ns.foaf(`preferredURI`))?.value??l};if(r.agentGroup.some(e=>e.uri in d))return{kind:`agentGroup`,subjectValue:l};if(r.agentClass.some(e=>u.sameTerm(e)))return{kind:`agentClass`,subjectValue:l}}exports.classifyAccessControlSubject=c;
2
2
  //# sourceMappingURL=accessControlSubjects.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"accessControlSubjects.cjs.js","names":[],"sources":["../../src/acl/accessControlSubjects.ts"],"sourcesContent":["import { LiveStore, sym } from 'rdflib'\nimport { ns } from '../util/ns'\n\nexport type AccessControlSubjectKind = 'agent' | 'agentGroup' | 'agentClass' | 'origin'\n\nexport type AccessControlSubject = {\n kind: AccessControlSubjectKind\n subjectValue: string\n}\n\nconst ACCESS_CONTROL_SUBJECT_GROUPS = {\n agentClass: [ns.foaf('Agent'), ns.acl('AuthenticatedAgent'), ns.rdf('Resource'), ns.owl('Thing')],\n agent: [ns.vcard('WebID'), ns.vcard('Individual'), ns.foaf('Person'), ns.foaf('Agent')],\n agentGroup: [ns.vcard('Group')],\n origin: [ns.solid('AppProvider'), ns.solid('AppProviderClass')]\n} as const\n\nfunction hasKnownTypes (types: Record<string, unknown>): boolean {\n return Object.keys(types).length > 0\n}\n\nfunction isHttpUrl (value: string): boolean {\n return value.startsWith('http://') || value.startsWith('https://')\n}\n\nfunction isBareOriginUrl (value: string): boolean {\n try {\n const parsed = new URL(value)\n return (parsed.protocol === 'http:' || parsed.protocol === 'https:') &&\n parsed.pathname === '/' &&\n !parsed.search &&\n !parsed.hash\n } catch (_error) {\n return false\n }\n}\n\nfunction normalizeOriginUrl (value: string): string {\n try {\n const parsed = new URL(value)\n if (\n (parsed.protocol === 'http:' || parsed.protocol === 'https:') &&\n parsed.pathname === '/' &&\n !parsed.search &&\n !parsed.hash\n ) {\n return `${parsed.protocol}//${parsed.host}`\n }\n } catch (_error) {\n // Return the original value below when parsing fails.\n }\n\n return value\n}\n\nexport async function classifyAccessControlSubject (store: LiveStore, principle: string): Promise<AccessControlSubject | undefined> {\n const subject = sym(principle)\n let types = store.findTypeURIs(subject)\n\n if (isBareOriginUrl(principle)) {\n return { kind: 'origin', subjectValue: normalizeOriginUrl(principle) }\n }\n\n if (!hasKnownTypes(types) && isHttpUrl(principle)) {\n try {\n await store.fetcher.load(subject.doc())\n } catch (error) {\n console.error(`Failed to load access target ${principle}`, error)\n }\n\n types = store.findTypeURIs(subject)\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.origin.some(term => term.uri in types)) {\n return { kind: 'origin', subjectValue: principle }\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.agent.some(term => term.uri in types)) {\n const preferredURI = store.any(subject, ns.foaf('preferredURI'))\n return {\n kind: 'agent',\n subjectValue: preferredURI?.value ?? principle\n }\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.agentGroup.some(term => term.uri in types)) {\n return { kind: 'agentGroup', subjectValue: principle }\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.agentClass.some(term => subject.sameTerm(term))) {\n return { kind: 'agentClass', subjectValue: principle }\n }\n\n return undefined\n}\n"],"mappings":"6DAUA,IAAM,EAAgC,CAClC,WAAY,CAAC,EAAA,GAAG,KAAK,OAAO,EAAG,EAAA,GAAG,IAAI,oBAAoB,EAAG,EAAA,GAAG,IAAI,UAAU,EAAG,EAAA,GAAG,IAAI,OAAO,CAAC,EAChG,MAAO,CAAC,EAAA,GAAG,MAAM,OAAO,EAAG,EAAA,GAAG,MAAM,YAAY,EAAG,EAAA,GAAG,KAAK,QAAQ,EAAG,EAAA,GAAG,KAAK,OAAO,CAAC,EACtF,WAAY,CAAC,EAAA,GAAG,MAAM,OAAO,CAAC,EAC9B,OAAQ,CAAC,EAAA,GAAG,MAAM,aAAa,EAAG,EAAA,GAAG,MAAM,kBAAkB,CAAC,CAClE,EAEA,SAAS,EAAe,EAAyC,CAC7D,OAAO,OAAO,KAAK,CAAK,CAAC,CAAC,OAAS,CACvC,CAEA,SAAS,EAAW,EAAwB,CACxC,OAAO,EAAM,WAAW,SAAS,GAAK,EAAM,WAAW,UAAU,CACrE,CAEA,SAAS,EAAiB,EAAwB,CAC9C,GAAI,CACA,IAAM,EAAS,IAAI,IAAI,CAAK,EAC5B,OAAQ,EAAO,WAAa,SAAW,EAAO,WAAa,WACvD,EAAO,WAAa,KACpB,CAAC,EAAO,QACR,CAAC,EAAO,IAChB,MAAiB,CACb,MAAO,EACX,CACJ,CAEA,SAAS,EAAoB,EAAuB,CAChD,GAAI,CACA,IAAM,EAAS,IAAI,IAAI,CAAK,EAC5B,IACK,EAAO,WAAa,SAAW,EAAO,WAAa,WACpD,EAAO,WAAa,KACpB,CAAC,EAAO,QACR,CAAC,EAAO,KAER,MAAO,GAAG,EAAO,SAAS,IAAI,EAAO,MAE7C,MAAiB,CAEjB,CAEA,OAAO,CACX,CAEA,eAAsB,EAA8B,EAAkB,EAA8D,CAChI,IAAM,GAAA,EAAU,EAAA,IAAA,CAAI,CAAS,EACzB,EAAQ,EAAM,aAAa,CAAO,EAEtC,GAAI,EAAgB,CAAS,EACzB,MAAO,CAAE,KAAM,SAAU,aAAc,EAAmB,CAAS,CAAE,EAGzE,GAAI,CAAC,EAAc,CAAK,GAAK,EAAU,CAAS,EAAG,CAC/C,GAAI,CACA,MAAM,EAAM,QAAQ,KAAK,EAAQ,IAAI,CAAC,CAC1C,OAAS,EAAO,CACZ,QAAQ,MAAM,gCAAgC,IAAa,CAAK,CACpE,CAEA,EAAQ,EAAM,aAAa,CAAO,CACtC,CAEA,GAAI,EAA8B,OAAO,KAAK,GAAQ,EAAK,OAAO,CAAK,EACnE,MAAO,CAAE,KAAM,SAAU,aAAc,CAAU,EAGrD,GAAI,EAA8B,MAAM,KAAK,GAAQ,EAAK,OAAO,CAAK,EAElE,MAAO,CACH,KAAM,QACN,aAHiB,EAAM,IAAI,EAAS,EAAA,GAAG,KAAK,cAAc,CAG5C,CAAA,EAAc,OAAS,CACzC,EAGJ,GAAI,EAA8B,WAAW,KAAK,GAAQ,EAAK,OAAO,CAAK,EACvE,MAAO,CAAE,KAAM,aAAc,aAAc,CAAU,EAGzD,GAAI,EAA8B,WAAW,KAAK,GAAQ,EAAQ,SAAS,CAAI,CAAC,EAC5E,MAAO,CAAE,KAAM,aAAc,aAAc,CAAU,CAI7D"}
1
+ {"version":3,"file":"accessControlSubjects.cjs.js","names":["ns","sym","error","require_debug","require_ns","rdflib","ACCESS_CONTROL_SUBJECT_GROUPS","hasKnownTypes","types","isHttpUrl","value","isBareOriginUrl","parsed","normalizeOriginUrl","classifyAccessControlSubject","subject","principle","store","error$1","term"],"sources":["../../src/acl/accessControlSubjects.ts"],"sourcesContent":["import { LiveStore, sym } from 'rdflib'\nimport { ns } from '../util/ns'\nimport * as debug from '../util/debug'\n\nexport type AccessControlSubjectKind = 'agent' | 'agentGroup' | 'agentClass' | 'origin'\n\nexport type AccessControlSubject = {\n kind: AccessControlSubjectKind\n subjectValue: string\n}\n\nconst ACCESS_CONTROL_SUBJECT_GROUPS = {\n agentClass: [ns.foaf('Agent'), ns.acl('AuthenticatedAgent'), ns.rdf('Resource'), ns.owl('Thing')],\n agent: [ns.vcard('WebID'), ns.vcard('Individual'), ns.foaf('Person'), ns.foaf('Agent')],\n agentGroup: [ns.vcard('Group')],\n origin: [ns.solid('AppProvider'), ns.solid('AppProviderClass')]\n} as const\n\nfunction hasKnownTypes (types: Record<string, unknown>): boolean {\n return Object.keys(types).length > 0\n}\n\nfunction isHttpUrl (value: string): boolean {\n return value.startsWith('http://') || value.startsWith('https://')\n}\n\nfunction isBareOriginUrl (value: string): boolean {\n try {\n const parsed = new URL(value)\n return (parsed.protocol === 'http:' || parsed.protocol === 'https:') &&\n Boolean(parsed.hostname) &&\n parsed.pathname === '/' &&\n !parsed.search &&\n !parsed.hash &&\n !parsed.username &&\n !parsed.password\n } catch (_error) {\n return false\n }\n}\n\nfunction normalizeOriginUrl (value: string): string {\n try {\n const parsed = new URL(value)\n if (\n (parsed.protocol === 'http:' || parsed.protocol === 'https:') &&\n parsed.hostname &&\n parsed.pathname === '/' &&\n !parsed.search &&\n !parsed.hash &&\n !parsed.username &&\n !parsed.password\n ) {\n return `${parsed.protocol}//${parsed.host}`\n }\n } catch (_error) {\n // Return the original value below when parsing fails.\n }\n\n return value\n}\n\nexport async function classifyAccessControlSubject (store: LiveStore, principle: string): Promise<AccessControlSubject | undefined> {\n const subject = sym(principle)\n let types = store.findTypeURIs(subject)\n\n if (isBareOriginUrl(principle)) {\n return { kind: 'origin', subjectValue: normalizeOriginUrl(principle) }\n }\n\n if (!hasKnownTypes(types) && isHttpUrl(principle)) {\n try {\n await store.fetcher.load(subject.doc())\n } catch (error) {\n debug.error(`Failed to load access target ${principle}`, error)\n }\n\n types = store.findTypeURIs(subject)\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.origin.some(term => term.uri in types)) {\n return { kind: 'origin', subjectValue: principle }\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.agent.some(term => term.uri in types)) {\n const preferredURI = store.any(subject, ns.foaf('preferredURI'))\n return {\n kind: 'agent',\n subjectValue: preferredURI?.value ?? principle\n }\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.agentGroup.some(term => term.uri in types)) {\n return { kind: 'agentGroup', subjectValue: principle }\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.agentClass.some(term => subject.sameTerm(term))) {\n return { kind: 'agentClass', subjectValue: principle }\n }\n\n return undefined\n}\n"],"mappings":"+FAWA,IAAMM,EAAgC,CAClC,WAAY,CAACN,EAAAA,GAAG,KAAK,OAAO,EAAGA,EAAAA,GAAG,IAAI,oBAAoB,EAAGA,EAAAA,GAAG,IAAI,UAAU,EAAGA,EAAAA,GAAG,IAAI,OAAO,CAAC,EAChG,MAAO,CAACA,EAAAA,GAAG,MAAM,OAAO,EAAGA,EAAAA,GAAG,MAAM,YAAY,EAAGA,EAAAA,GAAG,KAAK,QAAQ,EAAGA,EAAAA,GAAG,KAAK,OAAO,CAAC,EACtF,WAAY,CAACA,EAAAA,GAAG,MAAM,OAAO,CAAC,EAC9B,OAAQ,CAACA,EAAAA,GAAG,MAAM,aAAa,EAAGA,EAAAA,GAAG,MAAM,kBAAkB,CAAC,CAClE,EAEA,SAASO,EAAe,EAAyC,CAC7D,OAAO,OAAO,KAAKC,CAAK,CAAC,CAAC,OAAS,CACvC,CAEA,SAASC,EAAW,EAAwB,CACxC,OAAOC,EAAM,WAAW,SAAS,GAAKA,EAAM,WAAW,UAAU,CACrE,CAEA,SAASC,EAAiB,EAAwB,CAC9C,GAAI,CACA,IAAMC,EAAS,IAAI,IAAIF,CAAK,EAC5B,OAAQE,EAAO,WAAa,SAAWA,EAAO,WAAa,WACvD,EAAQA,EAAO,UACfA,EAAO,WAAa,KACpB,CAACA,EAAO,QACR,CAACA,EAAO,MACR,CAACA,EAAO,UACR,CAACA,EAAO,QAChB,MAAiB,CACb,MAAO,EACX,CACJ,CAEA,SAASC,EAAoB,EAAuB,CAChD,GAAI,CACA,IAAMD,EAAS,IAAI,IAAIF,CAAK,EAC5B,IACKE,EAAO,WAAa,SAAWA,EAAO,WAAa,WACpDA,EAAO,UACPA,EAAO,WAAa,KACpB,CAACA,EAAO,QACR,CAACA,EAAO,MACR,CAACA,EAAO,UACR,CAACA,EAAO,SAER,MAAO,GAAGA,EAAO,SAAS,IAAIA,EAAO,MAE7C,MAAiB,CAEjB,CAEA,OAAOF,CACX,CAEA,eAAsBI,EAA8B,EAAkB,EAA8D,CAChI,IAAMC,GAAA,EAAUd,EAAAA,IAAAA,CAAIe,CAAS,EACzBR,EAAQS,EAAM,aAAaF,CAAO,EAEtC,GAAIJ,EAAgBK,CAAS,EACzB,MAAO,CAAE,KAAM,SAAU,aAAcH,EAAmBG,CAAS,CAAE,EAGzE,GAAI,CAACT,EAAcC,CAAK,GAAKC,EAAUO,CAAS,EAAG,CAC/C,GAAI,CACA,MAAMC,EAAM,QAAQ,KAAKF,EAAQ,IAAI,CAAC,CAC1C,OAASb,EAAO,CACZC,EAAA,MAAY,gCAAgCa,IAAad,CAAK,CAClE,CAEA,EAAQe,EAAM,aAAaF,CAAO,CACtC,CAEA,GAAIT,EAA8B,OAAO,KAAK,GAAQa,EAAK,OAAOX,CAAK,EACnE,MAAO,CAAE,KAAM,SAAU,aAAcQ,CAAU,EAGrD,GAAIV,EAA8B,MAAM,KAAK,GAAQa,EAAK,OAAOX,CAAK,EAElE,MAAO,CACH,KAAM,QACN,aAHiBS,EAAM,IAAIF,EAASf,EAAAA,GAAG,KAAK,cAAc,CAG5C,CAAA,EAAc,OAASgB,CACzC,EAGJ,GAAIV,EAA8B,WAAW,KAAK,GAAQa,EAAK,OAAOX,CAAK,EACvE,MAAO,CAAE,KAAM,aAAc,aAAcQ,CAAU,EAGzD,GAAIV,EAA8B,WAAW,KAAK,GAAQS,EAAQ,SAASI,CAAI,CAAC,EAC5E,MAAO,CAAE,KAAM,aAAc,aAAcH,CAAU,CAI7D"}
@@ -1 +1 @@
1
- {"version":3,"file":"accessControlSubjects.d.ts","sourceRoot":"","sources":["../../src/acl/accessControlSubjects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAO,MAAM,QAAQ,CAAA;AAGvC,MAAM,MAAM,wBAAwB,GAAG,OAAO,GAAG,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAA;AAEvF,MAAM,MAAM,oBAAoB,GAAG;IAC/B,IAAI,EAAE,wBAAwB,CAAA;IAC9B,YAAY,EAAE,MAAM,CAAA;CACvB,CAAA;AA+CD,wBAAsB,4BAA4B,CAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAuClI"}
1
+ {"version":3,"file":"accessControlSubjects.d.ts","sourceRoot":"","sources":["../../src/acl/accessControlSubjects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAO,MAAM,QAAQ,CAAA;AAIvC,MAAM,MAAM,wBAAwB,GAAG,OAAO,GAAG,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAA;AAEvF,MAAM,MAAM,oBAAoB,GAAG;IAC/B,IAAI,EAAE,wBAAwB,CAAA;IAC9B,YAAY,EAAE,MAAM,CAAA;CACvB,CAAA;AAqDD,wBAAsB,4BAA4B,CAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAuClI"}
@@ -1,75 +1,76 @@
1
- import { ns as e } from "../util/ns.esm.js";
2
- import { sym as t } from "rdflib";
1
+ import { error as e } from "../util/debug.esm.js";
2
+ import { ns as t } from "../util/ns.esm.js";
3
+ import { sym as n } from "rdflib";
3
4
  //#region src/acl/accessControlSubjects.ts
4
- var n = {
5
+ var r = {
5
6
  agentClass: [
6
- e.foaf("Agent"),
7
- e.acl("AuthenticatedAgent"),
8
- e.rdf("Resource"),
9
- e.owl("Thing")
7
+ t.foaf("Agent"),
8
+ t.acl("AuthenticatedAgent"),
9
+ t.rdf("Resource"),
10
+ t.owl("Thing")
10
11
  ],
11
12
  agent: [
12
- e.vcard("WebID"),
13
- e.vcard("Individual"),
14
- e.foaf("Person"),
15
- e.foaf("Agent")
13
+ t.vcard("WebID"),
14
+ t.vcard("Individual"),
15
+ t.foaf("Person"),
16
+ t.foaf("Agent")
16
17
  ],
17
- agentGroup: [e.vcard("Group")],
18
- origin: [e.solid("AppProvider"), e.solid("AppProviderClass")]
18
+ agentGroup: [t.vcard("Group")],
19
+ origin: [t.solid("AppProvider"), t.solid("AppProviderClass")]
19
20
  };
20
- function r(e) {
21
+ function i(e) {
21
22
  return Object.keys(e).length > 0;
22
23
  }
23
- function i(e) {
24
+ function a(e) {
24
25
  return e.startsWith("http://") || e.startsWith("https://");
25
26
  }
26
- function a(e) {
27
+ function o(e) {
27
28
  try {
28
29
  let t = new URL(e);
29
- return (t.protocol === "http:" || t.protocol === "https:") && t.pathname === "/" && !t.search && !t.hash;
30
+ return (t.protocol === "http:" || t.protocol === "https:") && !!t.hostname && t.pathname === "/" && !t.search && !t.hash && !t.username && !t.password;
30
31
  } catch {
31
32
  return !1;
32
33
  }
33
34
  }
34
- function o(e) {
35
+ function s(e) {
35
36
  try {
36
37
  let t = new URL(e);
37
- if ((t.protocol === "http:" || t.protocol === "https:") && t.pathname === "/" && !t.search && !t.hash) return `${t.protocol}//${t.host}`;
38
+ if ((t.protocol === "http:" || t.protocol === "https:") && t.hostname && t.pathname === "/" && !t.search && !t.hash && !t.username && !t.password) return `${t.protocol}//${t.host}`;
38
39
  } catch {}
39
40
  return e;
40
41
  }
41
- async function s(s, c) {
42
- let l = t(c), u = s.findTypeURIs(l);
43
- if (a(c)) return {
42
+ async function c(c, l) {
43
+ let u = n(l), d = c.findTypeURIs(u);
44
+ if (o(l)) return {
44
45
  kind: "origin",
45
- subjectValue: o(c)
46
+ subjectValue: s(l)
46
47
  };
47
- if (!r(u) && i(c)) {
48
+ if (!i(d) && a(l)) {
48
49
  try {
49
- await s.fetcher.load(l.doc());
50
- } catch (e) {
51
- console.error(`Failed to load access target ${c}`, e);
50
+ await c.fetcher.load(u.doc());
51
+ } catch (t) {
52
+ e(`Failed to load access target ${l}`, t);
52
53
  }
53
- u = s.findTypeURIs(l);
54
+ d = c.findTypeURIs(u);
54
55
  }
55
- if (n.origin.some((e) => e.uri in u)) return {
56
+ if (r.origin.some((e) => e.uri in d)) return {
56
57
  kind: "origin",
57
- subjectValue: c
58
+ subjectValue: l
58
59
  };
59
- if (n.agent.some((e) => e.uri in u)) return {
60
+ if (r.agent.some((e) => e.uri in d)) return {
60
61
  kind: "agent",
61
- subjectValue: s.any(l, e.foaf("preferredURI"))?.value ?? c
62
+ subjectValue: c.any(u, t.foaf("preferredURI"))?.value ?? l
62
63
  };
63
- if (n.agentGroup.some((e) => e.uri in u)) return {
64
+ if (r.agentGroup.some((e) => e.uri in d)) return {
64
65
  kind: "agentGroup",
65
- subjectValue: c
66
+ subjectValue: l
66
67
  };
67
- if (n.agentClass.some((e) => l.sameTerm(e))) return {
68
+ if (r.agentClass.some((e) => u.sameTerm(e))) return {
68
69
  kind: "agentClass",
69
- subjectValue: c
70
+ subjectValue: l
70
71
  };
71
72
  }
72
73
  //#endregion
73
- export { s as classifyAccessControlSubject };
74
+ export { c as classifyAccessControlSubject };
74
75
 
75
76
  //# sourceMappingURL=accessControlSubjects.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"accessControlSubjects.esm.js","names":[],"sources":["../../src/acl/accessControlSubjects.ts"],"sourcesContent":["import { LiveStore, sym } from 'rdflib'\nimport { ns } from '../util/ns'\n\nexport type AccessControlSubjectKind = 'agent' | 'agentGroup' | 'agentClass' | 'origin'\n\nexport type AccessControlSubject = {\n kind: AccessControlSubjectKind\n subjectValue: string\n}\n\nconst ACCESS_CONTROL_SUBJECT_GROUPS = {\n agentClass: [ns.foaf('Agent'), ns.acl('AuthenticatedAgent'), ns.rdf('Resource'), ns.owl('Thing')],\n agent: [ns.vcard('WebID'), ns.vcard('Individual'), ns.foaf('Person'), ns.foaf('Agent')],\n agentGroup: [ns.vcard('Group')],\n origin: [ns.solid('AppProvider'), ns.solid('AppProviderClass')]\n} as const\n\nfunction hasKnownTypes (types: Record<string, unknown>): boolean {\n return Object.keys(types).length > 0\n}\n\nfunction isHttpUrl (value: string): boolean {\n return value.startsWith('http://') || value.startsWith('https://')\n}\n\nfunction isBareOriginUrl (value: string): boolean {\n try {\n const parsed = new URL(value)\n return (parsed.protocol === 'http:' || parsed.protocol === 'https:') &&\n parsed.pathname === '/' &&\n !parsed.search &&\n !parsed.hash\n } catch (_error) {\n return false\n }\n}\n\nfunction normalizeOriginUrl (value: string): string {\n try {\n const parsed = new URL(value)\n if (\n (parsed.protocol === 'http:' || parsed.protocol === 'https:') &&\n parsed.pathname === '/' &&\n !parsed.search &&\n !parsed.hash\n ) {\n return `${parsed.protocol}//${parsed.host}`\n }\n } catch (_error) {\n // Return the original value below when parsing fails.\n }\n\n return value\n}\n\nexport async function classifyAccessControlSubject (store: LiveStore, principle: string): Promise<AccessControlSubject | undefined> {\n const subject = sym(principle)\n let types = store.findTypeURIs(subject)\n\n if (isBareOriginUrl(principle)) {\n return { kind: 'origin', subjectValue: normalizeOriginUrl(principle) }\n }\n\n if (!hasKnownTypes(types) && isHttpUrl(principle)) {\n try {\n await store.fetcher.load(subject.doc())\n } catch (error) {\n console.error(`Failed to load access target ${principle}`, error)\n }\n\n types = store.findTypeURIs(subject)\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.origin.some(term => term.uri in types)) {\n return { kind: 'origin', subjectValue: principle }\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.agent.some(term => term.uri in types)) {\n const preferredURI = store.any(subject, ns.foaf('preferredURI'))\n return {\n kind: 'agent',\n subjectValue: preferredURI?.value ?? principle\n }\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.agentGroup.some(term => term.uri in types)) {\n return { kind: 'agentGroup', subjectValue: principle }\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.agentClass.some(term => subject.sameTerm(term))) {\n return { kind: 'agentClass', subjectValue: principle }\n }\n\n return undefined\n}\n"],"mappings":";;;AAUA,IAAM,IAAgC;CAClC,YAAY;EAAC,EAAG,KAAK,OAAO;EAAG,EAAG,IAAI,oBAAoB;EAAG,EAAG,IAAI,UAAU;EAAG,EAAG,IAAI,OAAO;CAAC;CAChG,OAAO;EAAC,EAAG,MAAM,OAAO;EAAG,EAAG,MAAM,YAAY;EAAG,EAAG,KAAK,QAAQ;EAAG,EAAG,KAAK,OAAO;CAAC;CACtF,YAAY,CAAC,EAAG,MAAM,OAAO,CAAC;CAC9B,QAAQ,CAAC,EAAG,MAAM,aAAa,GAAG,EAAG,MAAM,kBAAkB,CAAC;AAClE;AAEA,SAAS,EAAe,GAAyC;CAC7D,OAAO,OAAO,KAAK,CAAK,CAAC,CAAC,SAAS;AACvC;AAEA,SAAS,EAAW,GAAwB;CACxC,OAAO,EAAM,WAAW,SAAS,KAAK,EAAM,WAAW,UAAU;AACrE;AAEA,SAAS,EAAiB,GAAwB;CAC9C,IAAI;EACA,IAAM,IAAS,IAAI,IAAI,CAAK;EAC5B,QAAQ,EAAO,aAAa,WAAW,EAAO,aAAa,aACvD,EAAO,aAAa,OACpB,CAAC,EAAO,UACR,CAAC,EAAO;CAChB,QAAiB;EACb,OAAO;CACX;AACJ;AAEA,SAAS,EAAoB,GAAuB;CAChD,IAAI;EACA,IAAM,IAAS,IAAI,IAAI,CAAK;EAC5B,KACK,EAAO,aAAa,WAAW,EAAO,aAAa,aACpD,EAAO,aAAa,OACpB,CAAC,EAAO,UACR,CAAC,EAAO,MAER,OAAO,GAAG,EAAO,SAAS,IAAI,EAAO;CAE7C,QAAiB,CAEjB;CAEA,OAAO;AACX;AAEA,eAAsB,EAA8B,GAAkB,GAA8D;CAChI,IAAM,IAAU,EAAI,CAAS,GACzB,IAAQ,EAAM,aAAa,CAAO;CAEtC,IAAI,EAAgB,CAAS,GACzB,OAAO;EAAE,MAAM;EAAU,cAAc,EAAmB,CAAS;CAAE;CAGzE,IAAI,CAAC,EAAc,CAAK,KAAK,EAAU,CAAS,GAAG;EAC/C,IAAI;GACA,MAAM,EAAM,QAAQ,KAAK,EAAQ,IAAI,CAAC;EAC1C,SAAS,GAAO;GACZ,QAAQ,MAAM,gCAAgC,KAAa,CAAK;EACpE;EAEA,IAAQ,EAAM,aAAa,CAAO;CACtC;CAEA,IAAI,EAA8B,OAAO,MAAK,MAAQ,EAAK,OAAO,CAAK,GACnE,OAAO;EAAE,MAAM;EAAU,cAAc;CAAU;CAGrD,IAAI,EAA8B,MAAM,MAAK,MAAQ,EAAK,OAAO,CAAK,GAElE,OAAO;EACH,MAAM;EACN,cAHiB,EAAM,IAAI,GAAS,EAAG,KAAK,cAAc,CAG5C,CAAA,EAAc,SAAS;CACzC;CAGJ,IAAI,EAA8B,WAAW,MAAK,MAAQ,EAAK,OAAO,CAAK,GACvE,OAAO;EAAE,MAAM;EAAc,cAAc;CAAU;CAGzD,IAAI,EAA8B,WAAW,MAAK,MAAQ,EAAQ,SAAS,CAAI,CAAC,GAC5E,OAAO;EAAE,MAAM;EAAc,cAAc;CAAU;AAI7D"}
1
+ {"version":3,"file":"accessControlSubjects.esm.js","names":["error","ACCESS_CONTROL_SUBJECT_GROUPS","ns","hasKnownTypes","types","isHttpUrl","value","isBareOriginUrl","parsed","normalizeOriginUrl","classifyAccessControlSubject","subject","sym","principle","store","error$1","term"],"sources":["../../src/acl/accessControlSubjects.ts"],"sourcesContent":["import { LiveStore, sym } from 'rdflib'\nimport { ns } from '../util/ns'\nimport * as debug from '../util/debug'\n\nexport type AccessControlSubjectKind = 'agent' | 'agentGroup' | 'agentClass' | 'origin'\n\nexport type AccessControlSubject = {\n kind: AccessControlSubjectKind\n subjectValue: string\n}\n\nconst ACCESS_CONTROL_SUBJECT_GROUPS = {\n agentClass: [ns.foaf('Agent'), ns.acl('AuthenticatedAgent'), ns.rdf('Resource'), ns.owl('Thing')],\n agent: [ns.vcard('WebID'), ns.vcard('Individual'), ns.foaf('Person'), ns.foaf('Agent')],\n agentGroup: [ns.vcard('Group')],\n origin: [ns.solid('AppProvider'), ns.solid('AppProviderClass')]\n} as const\n\nfunction hasKnownTypes (types: Record<string, unknown>): boolean {\n return Object.keys(types).length > 0\n}\n\nfunction isHttpUrl (value: string): boolean {\n return value.startsWith('http://') || value.startsWith('https://')\n}\n\nfunction isBareOriginUrl (value: string): boolean {\n try {\n const parsed = new URL(value)\n return (parsed.protocol === 'http:' || parsed.protocol === 'https:') &&\n Boolean(parsed.hostname) &&\n parsed.pathname === '/' &&\n !parsed.search &&\n !parsed.hash &&\n !parsed.username &&\n !parsed.password\n } catch (_error) {\n return false\n }\n}\n\nfunction normalizeOriginUrl (value: string): string {\n try {\n const parsed = new URL(value)\n if (\n (parsed.protocol === 'http:' || parsed.protocol === 'https:') &&\n parsed.hostname &&\n parsed.pathname === '/' &&\n !parsed.search &&\n !parsed.hash &&\n !parsed.username &&\n !parsed.password\n ) {\n return `${parsed.protocol}//${parsed.host}`\n }\n } catch (_error) {\n // Return the original value below when parsing fails.\n }\n\n return value\n}\n\nexport async function classifyAccessControlSubject (store: LiveStore, principle: string): Promise<AccessControlSubject | undefined> {\n const subject = sym(principle)\n let types = store.findTypeURIs(subject)\n\n if (isBareOriginUrl(principle)) {\n return { kind: 'origin', subjectValue: normalizeOriginUrl(principle) }\n }\n\n if (!hasKnownTypes(types) && isHttpUrl(principle)) {\n try {\n await store.fetcher.load(subject.doc())\n } catch (error) {\n debug.error(`Failed to load access target ${principle}`, error)\n }\n\n types = store.findTypeURIs(subject)\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.origin.some(term => term.uri in types)) {\n return { kind: 'origin', subjectValue: principle }\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.agent.some(term => term.uri in types)) {\n const preferredURI = store.any(subject, ns.foaf('preferredURI'))\n return {\n kind: 'agent',\n subjectValue: preferredURI?.value ?? principle\n }\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.agentGroup.some(term => term.uri in types)) {\n return { kind: 'agentGroup', subjectValue: principle }\n }\n\n if (ACCESS_CONTROL_SUBJECT_GROUPS.agentClass.some(term => subject.sameTerm(term))) {\n return { kind: 'agentClass', subjectValue: principle }\n }\n\n return undefined\n}\n"],"mappings":";;;;AAWA,IAAMC,IAAgC;CAClC,YAAY;EAACC,EAAG,KAAK,OAAO;EAAGA,EAAG,IAAI,oBAAoB;EAAGA,EAAG,IAAI,UAAU;EAAGA,EAAG,IAAI,OAAO;CAAC;CAChG,OAAO;EAACA,EAAG,MAAM,OAAO;EAAGA,EAAG,MAAM,YAAY;EAAGA,EAAG,KAAK,QAAQ;EAAGA,EAAG,KAAK,OAAO;CAAC;CACtF,YAAY,CAACA,EAAG,MAAM,OAAO,CAAC;CAC9B,QAAQ,CAACA,EAAG,MAAM,aAAa,GAAGA,EAAG,MAAM,kBAAkB,CAAC;AAClE;AAEA,SAASC,EAAe,GAAyC;CAC7D,OAAO,OAAO,KAAKC,CAAK,CAAC,CAAC,SAAS;AACvC;AAEA,SAASC,EAAW,GAAwB;CACxC,OAAOC,EAAM,WAAW,SAAS,KAAKA,EAAM,WAAW,UAAU;AACrE;AAEA,SAASC,EAAiB,GAAwB;CAC9C,IAAI;EACA,IAAMC,IAAS,IAAI,IAAIF,CAAK;EAC5B,QAAQE,EAAO,aAAa,WAAWA,EAAO,aAAa,aACvD,EAAQA,EAAO,YACfA,EAAO,aAAa,OACpB,CAACA,EAAO,UACR,CAACA,EAAO,QACR,CAACA,EAAO,YACR,CAACA,EAAO;CAChB,QAAiB;EACb,OAAO;CACX;AACJ;AAEA,SAASC,EAAoB,GAAuB;CAChD,IAAI;EACA,IAAMD,IAAS,IAAI,IAAIF,CAAK;EAC5B,KACKE,EAAO,aAAa,WAAWA,EAAO,aAAa,aACpDA,EAAO,YACPA,EAAO,aAAa,OACpB,CAACA,EAAO,UACR,CAACA,EAAO,QACR,CAACA,EAAO,YACR,CAACA,EAAO,UAER,OAAO,GAAGA,EAAO,SAAS,IAAIA,EAAO;CAE7C,QAAiB,CAEjB;CAEA,OAAOF;AACX;AAEA,eAAsBI,EAA8B,GAAkB,GAA8D;CAChI,IAAMC,IAAUC,EAAIC,CAAS,GACzBT,IAAQU,EAAM,aAAaH,CAAO;CAEtC,IAAIJ,EAAgBM,CAAS,GACzB,OAAO;EAAE,MAAM;EAAU,cAAcJ,EAAmBI,CAAS;CAAE;CAGzE,IAAI,CAACV,EAAcC,CAAK,KAAKC,EAAUQ,CAAS,GAAG;EAC/C,IAAI;GACA,MAAMC,EAAM,QAAQ,KAAKH,EAAQ,IAAI,CAAC;EAC1C,SAASX,GAAO;GACZ,EAAY,gCAAgCa,KAAab,CAAK;EAClE;EAEA,IAAQc,EAAM,aAAaH,CAAO;CACtC;CAEA,IAAIV,EAA8B,OAAO,MAAK,MAAQe,EAAK,OAAOZ,CAAK,GACnE,OAAO;EAAE,MAAM;EAAU,cAAcS;CAAU;CAGrD,IAAIZ,EAA8B,MAAM,MAAK,MAAQe,EAAK,OAAOZ,CAAK,GAElE,OAAO;EACH,MAAM;EACN,cAHiBU,EAAM,IAAIH,GAAST,EAAG,KAAK,cAAc,CAG5C,CAAA,EAAc,SAASW;CACzC;CAGJ,IAAIZ,EAA8B,WAAW,MAAK,MAAQe,EAAK,OAAOZ,CAAK,GACvE,OAAO;EAAE,MAAM;EAAc,cAAcS;CAAU;CAGzD,IAAIZ,EAA8B,WAAW,MAAK,MAAQU,EAAQ,SAASK,CAAI,CAAC,GAC5E,OAAO;EAAE,MAAM;EAAc,cAAcH;CAAU;AAI7D"}
@@ -1,2 +1,2 @@
1
- const e=require("../util/ns.cjs.js"),t=require("./accessControlSubjects.cjs.js");let n=require("rdflib"),r=require("@dokieli/web-access-control");var i=[`Owner`,`Editor`,`No Access`,`Viewer`,`Poster`,`Submitter`],a=[`No Access`,`Viewer`],o=`Owner (write locked)`;function s(e,t,n=!1){let r=n&&(t.default?.length??0)>0,i=r||(t.accessTo?.includes(e)??!1),a=r||(t.default?.includes(e)??!1);if(i&&a)return`folder+contents`;if(i)return`folder`;if(a)return`contents`}function c(e,t,n,r=!1){return t.filter(t=>s(e,t,r)===n)}function l(e){return u(e).primaryScope}function u(e){let t=new Set;for(let n of e.authorizations??[]){let r=s(e.resource,n,e.inherited);r&&t.add(r)}if(!t.size){let n=new Map;for(let t of e.dataset??[]){if(t.object.value!==e.resource||t.predicate.value!==r.ACL+`accessTo`&&t.predicate.value!==r.ACL+`default`)continue;let i=n.get(t.subject.value)??{accessTo:!1,default:!1};i.accessTo||=t.predicate.value===r.ACL+`accessTo`,i.default||=t.predicate.value===r.ACL+`default`,n.set(t.subject.value,i)}for(let e of n.values())e.accessTo&&e.default?t.add(`folder+contents`):e.accessTo?t.add(`folder`):e.default&&t.add(`contents`)}let n=[...t];return{distinctScopes:n,primaryScope:n.includes(`folder+contents`)?`folder+contents`:n.includes(`contents`)?`contents`:n.includes(`folder`)?`folder`:`folder+contents`,mixed:n.length>1}}var d=(0,n.sym)(`http://www.iana.org/assignments/link-relations/acl`);function f(i){let s=e.ns,c=[{label:`Owner`,modes:[`Read`,`Write`,`Control`]},{label:o,modes:[`Read`,`Control`]},{label:`Editor`,modes:[`Read`,`Write`]},{label:`Poster`,modes:[`Append`,`Read`]},{label:`Submitter`,modes:[`Append`]},{label:`Viewer`,modes:[`Read`]},{label:`No Access`,modes:[]}],u=[{label:`Viewer`,modes:[`Read`]},{label:`No Access`,modes:[]}];function f(e){let t=new Set(e);return c.find(e=>e.modes.length===t.size&&e.modes.every(e=>t.has(e)))?.label??`No Access`}function p(e){return[...c.find(t=>t.label===e)?.modes??[]]}function m(e){let t=new Set(e);return u.find(e=>e.label!==`No Access`&&e.modes.every(e=>t.has(e)))?.label??`No Access`}function h(e){return[...u.find(t=>t.label===e)?.modes??[]]}function g(){let e=i.fetcher,t=e?._fetch??e?.fetch;if(!t)throw Error(`Cannot find effective ACL, store has no fetcher`);return t.bind(e)}async function _(e){await i.fetcher.load(e);let t=i.any(e,d);if(!t)throw Error(`No ACL link discovered for ${e}`);return t.value}async function v(e){let t=typeof e==`string`?e:e.value;return(0,r.findEffectiveACL)(t,{fetch:g()})}async function y(e){return(await v(e)).authorizations}function b(e){return l(e)}function x(e){let t=(0,n.sym)(typeof e==`string`?e:e.value);return t.value===t.site().value||typeof i.holds==`function`&&i.holds(t,s.rdf(`type`),s.space(`Storage`),t.doc())}function S(e,t){return t[{agent:`agent`,agentGroup:`agentGroup`,agentClass:`agentClass`,origin:`origin`}[e.type]]?.includes(e.iri)??!1}function C(e,t){if(!x(e.resource))return;let n=new Set(t.deletes.map(e=>e.subject.value)),i=new Map;for(let e of t.inserts){let t=i.get(e.subject.value)??{modes:[],accessTo:[]};e.predicate.value===r.ACL+`mode`?t.modes.push(e.object.value):e.predicate.value===r.ACL+`accessTo`&&t.accessTo.push(e.object.value),i.set(e.subject.value,t)}if(!(!e.inherited&&e.authorizations.some(t=>!n.has(t.id)&&t.mode.includes(`Control`)&&t.accessTo.includes(e.resource))||[...i.values()].some(t=>t.modes.includes(r.ACL+`Control`)&&t.accessTo.includes(e.resource))))throw Error(`The protected storage resource must retain at least one Control authorization.`)}function w(e,t){if(!new URL(e.resource).pathname.endsWith(`/`))return t;let n=t.inserts.filter(t=>t.predicate.value===r.ACL+`accessTo`&&t.object.value===e.resource).filter(n=>!t.inserts.some(t=>t.subject.equals(n.subject)&&t.predicate.value===r.ACL+`default`&&t.object.value===e.resource)).map(e=>(0,r.quad)(e.subject,(0,r.namedNode)(r.ACL+`default`),e.object));return{...t,inserts:[...t.inserts,...n]}}async function T(e,t,n){let i=await v(e);if(i.inherited&&new URL(i.resource).pathname.endsWith(`/`)){let e=N(i,t,n,`folder`);return C(i,e),e}let a=(0,r.planGrant)(i,t,n);return C(i,a),a}function E(e){if(!new URL(e.resource).pathname.endsWith(`/`))throw Error(`Expected a container URL ending in "/": ${e.resource}`)}let D=[`agent`,`agentClass`,`agentGroup`,`origin`],O=`http://www.w3.org/1999/02/22-rdf-syntax-ns#type`,k=new Set([O,r.ACL+`client`,r.ACL+`clientClass`,r.ACL+`clientGroup`,r.ACL+`issuer`,r.ACL+`issuerClass`,r.ACL+`issuerGroup`,r.ACL+`description`,r.ACL+`ClientCondition`,r.ACL+`IssuerCondition`]),A=new Set([r.ACL+`ClientCondition`,r.ACL+`IssuerCondition`]);function j(e){let t=new Set([...(e.dataset??[]).map(e=>e.subject.value),...e.authorizations.flatMap(e=>[e.id,...(e.condition??[]).map(e=>e.id)])]);return e=>{let n=e,r=1;for(;t.has(n);)n=`${e}-${r++}`;return t.add(n),n}}function M(e){for(let t of e.authorizations)for(let e of t.condition??[]){let t=e.properties[O]??[];if(t.length>1||t.length===1&&!A.has(t[0]))throw Error(`Unsupported ACL condition type on ${e.id}`);for(let t of Object.keys(e.properties))if(!k.has(t))throw Error(`Unsupported ACL condition property: ${t}`)}}function N(e,t,n,i,a=!1){let o=[],s=t.type,c=j(e);M(e);let l=(t,n,i,a)=>{let s=D.flatMap(e=>t[e].map(t=>({key:e,iri:t})));if(!s.length||!i.accessTo&&!i.default)return;let l=c(n),u=(0,r.namedNode)(l);o.push((0,r.quad)(u,(0,r.namedNode)(O),(0,r.namedNode)(r.ACL+`Authorization`)),...i.accessTo?[(0,r.quad)(u,(0,r.namedNode)(r.ACL+`accessTo`),(0,r.namedNode)(e.resource))]:[],...i.default?[(0,r.quad)(u,(0,r.namedNode)(r.ACL+`default`),(0,r.namedNode)(e.resource))]:[],...(a??t.mode).map(e=>(0,r.quad)(u,(0,r.namedNode)(r.ACL+`mode`),(0,r.namedNode)(`http://www.w3.org/ns/auth/acl#${e}`))),...s.map(({key:e,iri:t})=>(0,r.quad)(u,(0,r.namedNode)(r.ACL+e),(0,r.namedNode)(t))),...(t.condition??[]).flatMap(t=>{let n=c(`${l}-condition`),i=(0,r.namedNode)(n),a=e.dataset.filter(e=>e.subject.value===t.id).map(e=>(0,r.quad)(i,e.predicate,e.object));return[(0,r.quad)(u,(0,r.namedNode)(r.ACL+`condition`),i),...a]}))},u=e=>({...e,[s]:e[s].filter(e=>e!==t.iri)}),d=e=>({...e,agent:[],agentClass:[],agentGroup:[],origin:[],[s]:[t.iri]});if(e.authorizations.forEach((n,r)=>{let a=`${e.defaultACLResource}#inherited-${r+1}`,o=(n.default?.length??0)>0,c={accessTo:o||n.accessTo.includes(e.resource),default:o};if(!(n[s]?.includes(t.iri)??!1)){l(n,a,c);return}l(u(n),a,c),l(d(n),`${a}-retained`,{accessTo:c.accessTo&&i===`contents`,default:c.default&&i===`folder`})}),!a){let r=e.authorizations.find(e=>e[s]?.includes(t.iri)&&(e.default?.length??0)>0);l(d({id:`${e.defaultACLResource}#inherited-new-source`,blankNode:!1,accessTo:[],default:[],agent:[],agentClass:[],agentGroup:[],origin:[],mode:[],condition:r?.condition??[]}),`${e.defaultACLResource}#inherited-new`,{accessTo:i!==`contents`,default:i!==`folder`},n??[])}return{target:e.defaultACLResource,deletes:[],inserts:o}}async function P(e,t,n){let i=await v(e);E(i);let a=i.inherited?N(i,t,n,`folder`):(0,r.planGrant)(i,t,n);return C(i,a),a}async function F(e,t,n){let i=await v(e);E(i);let a=i.inherited?N(i,t,n,`folder+contents`):w(i,(0,r.planGrant)(i,t,n));return C(i,a),a}async function I(e,t,n){let i=await v(e);if(E(i),x(i.resource))throw Error(`Applying access to the contents of a protected storage resource is not allowed.`);if(i.inherited)return N(i,t,n,`contents`);let a=i.authorizations.filter(e=>e.default?.includes(i.resource)&&S(t,e));if(a.length)return R(i,a,t,n);let o=t.type,s=j(i)(`${i.defaultACLResource}#contents-1`),c=(0,r.namedNode)(s),l=(0,r.quad)(c,(0,r.namedNode)(r.ACL+o),(0,r.namedNode)(t.iri)),u=[(0,r.quad)(c,(0,r.namedNode)(O),(0,r.namedNode)(r.ACL+`Authorization`)),(0,r.quad)(c,(0,r.namedNode)(r.ACL+`default`),(0,r.namedNode)(i.resource)),...n.map(e=>(0,r.quad)(c,(0,r.namedNode)(r.ACL+`mode`),(0,r.namedNode)(`http://www.w3.org/ns/auth/acl#${e}`))),l];return{target:i.defaultACLResource,deletes:[],inserts:u}}async function L(e,t){let n=await v(e);if(E(n),x(n.resource))throw Error(`Removing access from the contents of a protected storage resource is not allowed.`);let i=r.ACL+`default`;if(!n.inherited){let e=n.authorizations.filter(e=>e.default?.includes(n.resource)&&S(t,e));if(e.length)return R(n,e,t);let r=n.dataset.filter(e=>e.predicate.value===i&&e.object.value===n.resource&&n.authorizations.some(n=>n.id===e.subject.value&&n[t.type].includes(t.iri)));if(!r.length)throw Error(`No default authorization found for ${t.iri}`);return{target:n.defaultACLResource,deletes:r,inserts:[]}}if(!n.authorizations.some(e=>e.default?.includes(n.resource)&&S(t,e)))throw Error(`No default authorization found for ${t.iri}`);return N(n,t,void 0,`contents`,!0)}function R(e,t,n,i){let a=j(e),o=[],s=(e,t,n,i,a,s)=>{t.length&&(i.length||a.length)&&o.push((0,r.quad)(e,(0,r.namedNode)(`http://www.w3.org/1999/02/22-rdf-syntax-ns#type`),(0,r.namedNode)(r.ACL+`Authorization`)),...i.map(t=>(0,r.quad)(e,(0,r.namedNode)(r.ACL+`accessTo`),(0,r.namedNode)(t))),...a.map(t=>(0,r.quad)(e,(0,r.namedNode)(r.ACL+`default`),(0,r.namedNode)(t))),...n.map(t=>(0,r.quad)(e,(0,r.namedNode)(r.ACL+`mode`),(0,r.namedNode)(`http://www.w3.org/ns/auth/acl#${t}`))),...s.map(t=>(0,r.quad)(e,(0,r.namedNode)(r.ACL+`condition`),(0,r.namedNode)(t))),...t.map(({key:t,iri:n})=>(0,r.quad)(e,(0,r.namedNode)(r.ACL+t),(0,r.namedNode)(n))))},c=[];return t.forEach((t,o)=>{let l=D.flatMap(e=>t[e].map(t=>({key:e,iri:t}))),u=l.filter(({key:e,iri:t})=>e!==n.type||t!==n.iri),d=`${e.defaultACLResource}#split-${o+1}`;if(!i&&l.length===1&&u.length===0){c.push(...e.dataset.filter(n=>n.subject.value===t.id&&n.predicate.value===r.ACL+`default`&&n.object.value===e.resource));return}c.push(...e.dataset.filter(e=>e.subject.value===t.id));let f=(t.condition??[]).map(e=>e.id);s((0,r.namedNode)(a(`${e.defaultACLResource}#retained-${o+1}`)),u,t.mode,t.accessTo,t.default,f);let p=t.default.filter(t=>t!==e.resource);(t.accessTo.length||p.length)&&s((0,r.namedNode)(a(`${d}-retained`)),[{key:n.type,iri:n.iri}],t.mode,t.accessTo,p,f),i&&s((0,r.namedNode)(a(`${d}`)),[{key:n.type,iri:n.iri}],i,[],t.default.filter(t=>t===e.resource),f)}),{target:e.defaultACLResource,deletes:c,inserts:o}}async function z(e,t){let n=await v(e);if(n.inherited&&new URL(n.resource).pathname.endsWith(`/`)){let e=N(n,t,void 0,`folder+contents`,!0);return C(n,e),e}let i=w(n,(0,r.planRevoke)(n,t));return C(n,i),i}async function B(e,t){let n=await v(e);return(0,r.planPublicRead)(n,t)}async function V(e){let t=await v(e);if(x(t.resource))throw Error(`The protected storage resource cannot be reset to a default ACL.`);let n=await g()(t.defaultACLResource,{method:`DELETE`});if(!n.ok&&n.status!==404)throw Error(`Unable to remove ACL ${t.defaultACLResource}: HTTP ${n.status}`);return n}async function H(e){return(0,r.applyPlan)(e,{fetch:g()})}async function U(e){return t.classifyAccessControlSubject(i,e)}function W(e,t,n){let r=i.any(i.sym(e),d);return Promise.resolve().then(()=>r||G(e).catch(t=>{throw Error(`Error fetching rel=ACL header for ${e}: ${t}`)})).then(r=>{let a=K(e,t,r.uri,n);if(!i.fetcher)throw Error(`Cannot PUT this, store has no fetcher`);return i.fetcher.webOperation(`PUT`,r.uri,{data:a,contentType:`text/turtle`}).then(e=>{if(!e.ok)throw Error(`Error writing ACL text: `+e.error);return r})})}function G(e){let t=i.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 n=i.any(i.sym(e),d);if(!n)throw Error(`fetchACLRel: No Link rel=ACL header for `+e);return n})}function K(e,t,r,i={}){let a=i.public||[],o=(0,n.graph)(),c=(0,n.Namespace)(`http://www.w3.org/ns/auth/acl#`),l=o.sym(`${r}#a1`),u=o.sym(r),d=o.sym(e);if(o.add(l,s.rdf(`type`),c(`Authorization`),u),o.add(l,c(`accessTo`),d,u),i.defaultForNew&&o.add(l,c(`default`),d,u),o.add(l,c(`agent`),t,u),o.add(l,c(`mode`),c(`Read`),u),o.add(l,c(`mode`),c(`Write`),u),o.add(l,c(`mode`),c(`Control`),u),a.length){l=o.sym(`${r}#a2`),o.add(l,s.rdf(`type`),c(`Authorization`),u),o.add(l,c(`accessTo`),d,u),o.add(l,c(`agentClass`),s.foaf(`Agent`),u);for(let e=0;e<a.length;e++)o.add(l,c(`mode`),c(a[e]),u)}return(0,n.serialize)(u,o,r)}return{findAclDocUrl:_,findEffectiveAcl:v,findAccessGrants:y,classifyContainerScope:b,isProtectedResource:x,roleFromModes:f,modesFromRole:p,publicRoleFromModes:m,modesFromPublicRole:h,planGrant:T,planGrantContainer:P,planGrantContainerAndContents:F,planGrantContainerContents:I,planRevokeContainerContents:L,planRevoke:z,planPublicRead:B,resetToDefault:V,applyPlan:H,classifyAccessControlSubject:U,setACLUserPublic:W,genACLText:K,Authenticated:r.Authenticated,Public:r.Public,PUBLIC_ACCESS_ROLES:a}}exports.ACCESS_ROLES=i,exports.ACL_LINK=d,exports.PUBLIC_ACCESS_ROLES=a,exports.WRITE_LOCKED_OWNER_ROLE=o,exports.analyzeContainerAccessScope=u,exports.classifyAuthorizationScope=s,exports.classifyContainerAccessScope=l,exports.createAclLogic=f,exports.filterAuthorizationsByContainerScope=c;
1
+ const e=require("../util/ns.cjs.js"),t=require("./accessControlSubjects.cjs.js");let n=require("rdflib"),r=require("@dokieli/web-access-control");var i=[`Owner`,`Editor`,`No Access`,`Viewer`,`Poster`,`Submitter`],a=[`No Access`,`Viewer`],o=`Owner (write locked)`;function s(e,t,n=!1){let r=n&&(t.default?.length??0)>0,i=r||(t.accessTo?.includes(e)??!1),a=r||(t.default?.includes(e)??!1);if(i&&a)return`folder+contents`;if(i)return`folder`;if(a)return`contents`}function c(e,t,n,r=!1){return t.filter(t=>s(e,t,r)===n)}function l(e){return u(e).primaryScope}function u(e){let t=new Set;for(let n of e.authorizations??[]){let r=s(e.resource,n,e.inherited);r&&t.add(r)}if(!t.size){let n=new Map;for(let t of e.dataset??[]){if(t.object.value!==e.resource||t.predicate.value!==r.ACL+`accessTo`&&t.predicate.value!==r.ACL+`default`)continue;let i=n.get(t.subject.value)??{accessTo:!1,default:!1};i.accessTo||=t.predicate.value===r.ACL+`accessTo`,i.default||=t.predicate.value===r.ACL+`default`,n.set(t.subject.value,i)}for(let e of n.values())e.accessTo&&e.default?t.add(`folder+contents`):e.accessTo?t.add(`folder`):e.default&&t.add(`contents`)}let n=[...t];return{distinctScopes:n,primaryScope:n.includes(`folder+contents`)?`folder+contents`:n.includes(`contents`)?`contents`:n.includes(`folder`)?`folder`:`folder+contents`,mixed:n.length>1}}var d=(0,n.sym)(`http://www.iana.org/assignments/link-relations/acl`);function f(i){let s=e.ns,c=[{label:`Owner`,modes:[`Read`,`Write`,`Control`]},{label:o,modes:[`Read`,`Control`]},{label:`Editor`,modes:[`Read`,`Write`]},{label:`Poster`,modes:[`Append`,`Read`]},{label:`Submitter`,modes:[`Append`]},{label:`Viewer`,modes:[`Read`]},{label:`No Access`,modes:[]}],u=[{label:`Viewer`,modes:[`Read`]},{label:`No Access`,modes:[]}];function f(e){let t=new Set(e);return c.find(e=>e.modes.length===t.size&&e.modes.every(e=>t.has(e)))?.label??`No Access`}function p(e){return[...c.find(t=>t.label===e)?.modes??[]]}function m(e){let t=new Set(e);return u.find(e=>e.label!==`No Access`&&e.modes.every(e=>t.has(e)))?.label??`No Access`}function h(e){return[...u.find(t=>t.label===e)?.modes??[]]}function g(){let e=i.fetcher,t=e?._fetch??e?.fetch;if(!t)throw Error(`Cannot find effective ACL, store has no fetcher`);return t.bind(e)}async function _(e){await i.fetcher.load(e);let t=i.any(e,d);if(!t)throw Error(`No ACL link discovered for ${e}`);return t.value}async function v(e){let t=typeof e==`string`?e:e.value;return(0,r.findEffectiveACL)(t,{fetch:g()})}async function y(e){return(await v(e)).authorizations}function b(e){return l(e)}function x(e){let t=(0,n.sym)(typeof e==`string`?e:e.value);return t.value===t.site().value||typeof i.holds==`function`&&i.holds(t,s.rdf(`type`),s.space(`Storage`),t.doc())}function S(e,t){return t[{agent:`agent`,agentGroup:`agentGroup`,agentClass:`agentClass`,origin:`origin`}[e.type]]?.includes(e.iri)??!1}function C(e,t){if(!x(e.resource))return;let n=new Set(t.deletes.map(e=>e.subject.value)),i=new Map;for(let e of t.inserts){let t=i.get(e.subject.value)??{modes:[],accessTo:[]};e.predicate.value===r.ACL+`mode`?t.modes.push(e.object.value):e.predicate.value===r.ACL+`accessTo`&&t.accessTo.push(e.object.value),i.set(e.subject.value,t)}if(!(!e.inherited&&e.authorizations.some(t=>!n.has(t.id)&&t.mode.includes(`Control`)&&t.accessTo.includes(e.resource))||[...i.values()].some(t=>t.modes.includes(r.ACL+`Control`)&&t.accessTo.includes(e.resource))))throw Error(`The protected storage resource must retain at least one Control authorization.`)}function w(e,t){if(!new URL(e.resource).pathname.endsWith(`/`))return t;let n=t.inserts.filter(t=>t.predicate.value===r.ACL+`accessTo`&&t.object.value===e.resource).filter(n=>!t.inserts.some(t=>t.subject.equals(n.subject)&&t.predicate.value===r.ACL+`default`&&t.object.value===e.resource)).map(e=>(0,r.quad)(e.subject,(0,r.namedNode)(r.ACL+`default`),e.object));return{...t,inserts:[...t.inserts,...n]}}async function T(e,t,n){let i=await v(e);if(i.inherited&&new URL(i.resource).pathname.endsWith(`/`)){let e=N(i,t,n,`folder`);return C(i,e),e}let a=(0,r.planGrant)(i,t,n);return C(i,a),a}function E(e){if(!new URL(e.resource).pathname.endsWith(`/`))throw Error(`Expected a container URL ending in "/": ${e.resource}`)}let D=[`agent`,`agentClass`,`agentGroup`,`origin`],O=`http://www.w3.org/1999/02/22-rdf-syntax-ns#type`,k=new Set([O,r.ACL+`client`,r.ACL+`clientClass`,r.ACL+`clientGroup`,r.ACL+`issuer`,r.ACL+`issuerClass`,r.ACL+`issuerGroup`,r.ACL+`description`,r.ACL+`ClientCondition`,r.ACL+`IssuerCondition`]),A=new Set([r.ACL+`ClientCondition`,r.ACL+`IssuerCondition`]);function j(e){let t=new Set([...(e.dataset??[]).map(e=>e.subject.value),...e.authorizations.flatMap(e=>[e.id,...(e.condition??[]).map(e=>e.id)])]);return e=>{let n=e,r=1;for(;t.has(n);)n=`${e}-${r++}`;return t.add(n),n}}function M(e){for(let t of e.authorizations)for(let e of t.condition??[]){let t=e.properties[O]??[];if(t.length>1||t.length===1&&!A.has(t[0]))throw Error(`Unsupported ACL condition type on ${e.id}`);for(let t of Object.keys(e.properties))if(!k.has(t))throw Error(`Unsupported ACL condition property: ${t}`)}}function N(e,t,n,i,a=!1){let o=[],s=t.type,c=j(e);M(e);let l=(t,n,i,a)=>{let s=D.flatMap(e=>t[e].map(t=>({key:e,iri:t})));if(!s.length||!i.accessTo&&!i.default)return;let l=c(n),u=(0,r.namedNode)(l);o.push((0,r.quad)(u,(0,r.namedNode)(O),(0,r.namedNode)(r.ACL+`Authorization`)),...i.accessTo?[(0,r.quad)(u,(0,r.namedNode)(r.ACL+`accessTo`),(0,r.namedNode)(e.resource))]:[],...i.default?[(0,r.quad)(u,(0,r.namedNode)(r.ACL+`default`),(0,r.namedNode)(e.resource))]:[],...(a??t.mode).map(e=>(0,r.quad)(u,(0,r.namedNode)(r.ACL+`mode`),(0,r.namedNode)(`http://www.w3.org/ns/auth/acl#${e}`))),...s.map(({key:e,iri:t})=>(0,r.quad)(u,(0,r.namedNode)(r.ACL+e),(0,r.namedNode)(t))),...(t.condition??[]).flatMap(t=>{let n=c(`${l}-condition`),i=(0,r.namedNode)(n),a=e.dataset.filter(e=>e.subject.value===t.id).map(e=>(0,r.quad)(i,e.predicate,e.object));return[(0,r.quad)(u,(0,r.namedNode)(r.ACL+`condition`),i),...a]}))},u=e=>({...e,[s]:e[s].filter(e=>e!==t.iri)}),d=e=>({...e,agent:[],agentClass:[],agentGroup:[],origin:[],[s]:[t.iri]});if(e.authorizations.forEach((n,r)=>{let a=`${e.defaultACLResource}#inherited-${r+1}`,o=(n.default?.length??0)>0,c={accessTo:o||n.accessTo.includes(e.resource),default:o};n[s]?.includes(t.iri)??!1?(l(u(n),a,c),l(d(n),`${a}-retained`,{accessTo:c.accessTo&&i===`contents`,default:c.default&&i===`folder`})):l(n,a,c)}),!a){let r=e.authorizations.find(e=>e[s]?.includes(t.iri)&&(e.default?.length??0)>0);l(d({id:`${e.defaultACLResource}#inherited-new-source`,blankNode:!1,accessTo:[],default:[],agent:[],agentClass:[],agentGroup:[],origin:[],mode:[],condition:r?.condition??[]}),`${e.defaultACLResource}#inherited-new`,{accessTo:i!==`contents`,default:i!==`folder`},n??[])}return{target:e.defaultACLResource,deletes:[],inserts:o}}async function P(e,t,n){let i=await v(e);E(i);let a=i.inherited?N(i,t,n,`folder`):(0,r.planGrant)(i,t,n);return C(i,a),a}async function F(e,t,n){let i=await v(e);E(i);let a=i.inherited?N(i,t,n,`folder+contents`):w(i,(0,r.planGrant)(i,t,n));return C(i,a),a}async function I(e,t,n){let i=await v(e);if(E(i),x(i.resource))throw Error(`Applying access to the contents of a protected storage resource is not allowed.`);if(i.inherited)return N(i,t,n,`contents`);let a=i.authorizations.filter(e=>e.default?.includes(i.resource)&&S(t,e));if(a.length)return R(i,a,t,n);let o=t.type,s=j(i)(`${i.defaultACLResource}#contents-1`),c=(0,r.namedNode)(s),l=(0,r.quad)(c,(0,r.namedNode)(r.ACL+o),(0,r.namedNode)(t.iri)),u=[(0,r.quad)(c,(0,r.namedNode)(O),(0,r.namedNode)(r.ACL+`Authorization`)),(0,r.quad)(c,(0,r.namedNode)(r.ACL+`default`),(0,r.namedNode)(i.resource)),...n.map(e=>(0,r.quad)(c,(0,r.namedNode)(r.ACL+`mode`),(0,r.namedNode)(`http://www.w3.org/ns/auth/acl#${e}`))),l];return{target:i.defaultACLResource,deletes:[],inserts:u}}async function L(e,t){let n=await v(e);if(E(n),x(n.resource))throw Error(`Removing access from the contents of a protected storage resource is not allowed.`);let i=r.ACL+`default`;if(!n.inherited){let e=n.authorizations.filter(e=>e.default?.includes(n.resource)&&S(t,e));if(e.length)return R(n,e,t);let r=n.dataset.filter(e=>e.predicate.value===i&&e.object.value===n.resource&&n.authorizations.some(n=>n.id===e.subject.value&&n[t.type].includes(t.iri)));if(!r.length)throw Error(`No default authorization found for ${t.iri}`);return{target:n.defaultACLResource,deletes:r,inserts:[]}}if(!n.authorizations.some(e=>e.default?.includes(n.resource)&&S(t,e)))throw Error(`No default authorization found for ${t.iri}`);return N(n,t,void 0,`contents`,!0)}function R(e,t,n,i){let a=j(e),o=[],s=(e,t,n,i,a,s)=>{t.length&&(i.length||a.length)&&o.push((0,r.quad)(e,(0,r.namedNode)(`http://www.w3.org/1999/02/22-rdf-syntax-ns#type`),(0,r.namedNode)(r.ACL+`Authorization`)),...i.map(t=>(0,r.quad)(e,(0,r.namedNode)(r.ACL+`accessTo`),(0,r.namedNode)(t))),...a.map(t=>(0,r.quad)(e,(0,r.namedNode)(r.ACL+`default`),(0,r.namedNode)(t))),...n.map(t=>(0,r.quad)(e,(0,r.namedNode)(r.ACL+`mode`),(0,r.namedNode)(`http://www.w3.org/ns/auth/acl#${t}`))),...s.map(t=>(0,r.quad)(e,(0,r.namedNode)(r.ACL+`condition`),(0,r.namedNode)(t))),...t.map(({key:t,iri:n})=>(0,r.quad)(e,(0,r.namedNode)(r.ACL+t),(0,r.namedNode)(n))))},c=[];return t.forEach((t,o)=>{let l=D.flatMap(e=>t[e].map(t=>({key:e,iri:t}))),u=l.filter(({key:e,iri:t})=>e!==n.type||t!==n.iri),d=`${e.defaultACLResource}#split-${o+1}`;if(!i&&l.length===1&&u.length===0){c.push(...e.dataset.filter(n=>n.subject.value===t.id&&n.predicate.value===r.ACL+`default`&&n.object.value===e.resource));return}c.push(...e.dataset.filter(e=>e.subject.value===t.id));let f=(t.condition??[]).map(e=>e.id);s((0,r.namedNode)(a(`${e.defaultACLResource}#retained-${o+1}`)),u,t.mode,t.accessTo,t.default,f);let p=t.default.filter(t=>t!==e.resource);(t.accessTo.length||p.length)&&s((0,r.namedNode)(a(`${d}-retained`)),[{key:n.type,iri:n.iri}],t.mode,t.accessTo,p,f),i&&s((0,r.namedNode)(a(`${d}`)),[{key:n.type,iri:n.iri}],i,[],t.default.filter(t=>t===e.resource),f)}),{target:e.defaultACLResource,deletes:c,inserts:o}}async function z(e,t){let n=await v(e);if(n.inherited&&new URL(n.resource).pathname.endsWith(`/`)){let e=N(n,t,void 0,`folder+contents`,!0);return C(n,e),e}let i=w(n,(0,r.planRevoke)(n,t));return C(n,i),i}async function B(e,t){let n=await v(e);return(0,r.planPublicRead)(n,t)}async function V(e){let t=await v(e);if(x(t.resource))throw Error(`The protected storage resource cannot be reset to a default ACL.`);let n=await g()(t.defaultACLResource,{method:`DELETE`});if(!n.ok&&n.status!==404)throw Error(`Unable to remove ACL ${t.defaultACLResource}: HTTP ${n.status}`);return n}async function H(e){return(0,r.applyPlan)(e,{fetch:g()})}async function U(e){return t.classifyAccessControlSubject(i,e)}function W(e,t,n){let r=i.any(i.sym(e),d);return Promise.resolve().then(()=>r||G(e).catch(t=>{throw Error(`Error fetching rel=ACL header for ${e}: ${t}`)})).then(r=>{let a=K(e,t,r.uri,n);if(!i.fetcher)throw Error(`Cannot PUT this, store has no fetcher`);return i.fetcher.webOperation(`PUT`,r.uri,{data:a,contentType:`text/turtle`}).then(e=>{if(!e.ok)throw Error(`Error writing ACL text: `+e.error);return r})})}function G(e){let t=i.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 n=i.any(i.sym(e),d);if(!n)throw Error(`fetchACLRel: No Link rel=ACL header for `+e);return n})}function K(e,t,r,i={}){let a=i.public||[],o=(0,n.graph)(),c=(0,n.Namespace)(`http://www.w3.org/ns/auth/acl#`),l=o.sym(`${r}#a1`),u=o.sym(r),d=o.sym(e);if(o.add(l,s.rdf(`type`),c(`Authorization`),u),o.add(l,c(`accessTo`),d,u),i.defaultForNew&&o.add(l,c(`default`),d,u),o.add(l,c(`agent`),t,u),o.add(l,c(`mode`),c(`Read`),u),o.add(l,c(`mode`),c(`Write`),u),o.add(l,c(`mode`),c(`Control`),u),a.length){l=o.sym(`${r}#a2`),o.add(l,s.rdf(`type`),c(`Authorization`),u),o.add(l,c(`accessTo`),d,u),o.add(l,c(`agentClass`),s.foaf(`Agent`),u);for(let e=0;e<a.length;e++)o.add(l,c(`mode`),c(a[e]),u)}return(0,n.serialize)(u,o,r)}return{findAclDocUrl:_,findEffectiveAcl:v,findAccessGrants:y,classifyContainerScope:b,isProtectedResource:x,roleFromModes:f,modesFromRole:p,publicRoleFromModes:m,modesFromPublicRole:h,planGrant:T,planGrantContainer:P,planGrantContainerAndContents:F,planGrantContainerContents:I,planRevokeContainerContents:L,planRevoke:z,planPublicRead:B,resetToDefault:V,applyPlan:H,classifyAccessControlSubject:U,setACLUserPublic:W,genACLText:K,Authenticated:r.Authenticated,Public:r.Public,PUBLIC_ACCESS_ROLES:a}}exports.ACCESS_ROLES=i,exports.ACL_LINK=d,exports.PUBLIC_ACCESS_ROLES=a,exports.WRITE_LOCKED_OWNER_ROLE=o,exports.analyzeContainerAccessScope=u,exports.classifyAuthorizationScope=s,exports.classifyContainerAccessScope=l,exports.createAclLogic=f,exports.filterAuthorizationsByContainerScope=c;
2
2
  //# sourceMappingURL=aclLogic.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"aclLogic.cjs.js","names":[],"sources":["../../src/acl/aclLogic.ts"],"sourcesContent":["import { ACL, namedNode, quad, applyPlan as applyAuthorizationPlan, Authenticated, findEffectiveACL, planGrant as planAuthorizationGrant, planPublicRead as planAuthorizationPublicRead, planRevoke as planAuthorizationRevoke, Public, type AccessMode, type AccessSubject, type ACLContext, type Authorization, type PatchPlan } from '@dokieli/web-access-control'\nimport { graph, NamedNode, Namespace, serialize, sym } from 'rdflib'\nimport type { AclLogic } from '../types'\nimport { ns as namespace } from '../util/ns'\nimport * as accessControlSubjects from './accessControlSubjects'\n\nexport const ACCESS_ROLES = ['Owner', 'Editor', 'No Access', 'Viewer', 'Poster', 'Submitter'] as const\nexport const PUBLIC_ACCESS_ROLES = ['No Access', 'Viewer'] as const\n/**\n * A Control grant without Write is the legacy \"write locked\" owner grant.\n *\n * It is intentionally not part of ACCESS_ROLES yet: that list is consumed by\n * the existing UI, whose selector will be updated in a later change.\n */\nexport const WRITE_LOCKED_OWNER_ROLE = 'Owner (write locked)' as const\nexport { Authenticated, Public } from '@dokieli/web-access-control'\n\nexport type AccessRole = typeof ACCESS_ROLES[number] | typeof WRITE_LOCKED_OWNER_ROLE\nexport type PublicAccessRole = typeof PUBLIC_ACCESS_ROLES[number]\nexport type ContainerAccessScope = 'folder+contents' | 'folder' | 'contents'\nexport interface ContainerAccessScopeResult {\n distinctScopes: ContainerAccessScope[]\n primaryScope: ContainerAccessScope\n mixed: boolean\n}\nexport function classifyAuthorizationScope (\n resource: string,\n authorization: Authorization,\n inherited = false\n): ContainerAccessScope | undefined {\n // Effective ACL discovery keeps inherited `acl:default` targets on the\n // parent container. They govern both this container and its contents\n // (legacy adoptACLDefault copies them as accessTo + default).\n const inheritedDefault = inherited && (authorization.default?.length ?? 0) > 0\n const hasAccessTo = inheritedDefault || (authorization.accessTo?.includes(resource) ?? false)\n const hasDefault = inheritedDefault || (authorization.default?.includes(resource) ?? false)\n if (hasAccessTo && hasDefault) return 'folder+contents'\n if (hasAccessTo) return 'folder'\n if (hasDefault) return 'contents'\n return undefined\n}\n\nexport function filterAuthorizationsByContainerScope (\n resource: string,\n authorizations: Authorization[],\n scope: ContainerAccessScope,\n inherited = false\n): Authorization[] {\n return authorizations.filter(authorization =>\n classifyAuthorizationScope(resource, authorization, inherited) === scope\n )\n}\n\n/**\n * Classify the direct ACL predicates for a container. Mixed grants are\n * conservatively treated as covering both scopes.\n */\nexport function classifyContainerAccessScope (context: ACLContext): ContainerAccessScope {\n return analyzeContainerAccessScope(context).primaryScope\n}\n\nexport function analyzeContainerAccessScope (context: ACLContext): ContainerAccessScopeResult {\n const scopes = new Set<ContainerAccessScope>()\n for (const authorization of context.authorizations ?? []) {\n const scope = classifyAuthorizationScope(context.resource, authorization, context.inherited)\n if (scope) scopes.add(scope)\n }\n // Older callers may provide only the graph. Preserve their classification\n // while keeping the authorization-entry semantics for parsed contexts.\n if (!scopes.size) {\n const entries = new Map<string, { accessTo: boolean, default: boolean }>()\n for (const statement of context.dataset ?? []) {\n if (statement.object.value !== context.resource) continue\n if (statement.predicate.value !== ACL + 'accessTo' && statement.predicate.value !== ACL + 'default') continue\n const entry = entries.get(statement.subject.value) ?? { accessTo: false, default: false }\n entry.accessTo ||= statement.predicate.value === ACL + 'accessTo'\n entry.default ||= statement.predicate.value === ACL + 'default'\n entries.set(statement.subject.value, entry)\n }\n for (const entry of entries.values()) {\n if (entry.accessTo && entry.default) scopes.add('folder+contents')\n else if (entry.accessTo) scopes.add('folder')\n else if (entry.default) scopes.add('contents')\n }\n }\n const distinctScopes = [...scopes]\n const primaryScope = distinctScopes.includes('folder+contents')\n ? 'folder+contents'\n : distinctScopes.includes('contents')\n ? 'contents'\n : distinctScopes.includes('folder')\n ? 'folder'\n : 'folder+contents'\n return { distinctScopes, primaryScope, mixed: distinctScopes.length > 1 }\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 const ACCESS_ROLE_RULES: Array<{ label: AccessRole, modes: AccessMode[] }> = [\n { label: 'Owner', modes: ['Read', 'Write', 'Control'] },\n { label: WRITE_LOCKED_OWNER_ROLE, modes: ['Read', 'Control'] },\n { label: 'Editor', modes: ['Read', 'Write'] },\n { label: 'Poster', modes: ['Append', 'Read'] },\n { label: 'Submitter', modes: ['Append'] },\n { label: 'Viewer', modes: ['Read'] },\n { label: 'No Access', modes: [] }\n ]\n const PUBLIC_ROLE_RULES: Array<{ label: PublicAccessRole, modes: AccessMode[] }> = [\n { label: 'Viewer', modes: ['Read'] },\n { label: 'No Access', modes: [] }\n ]\n\n function roleFromModes (modes: Iterable<AccessMode>): AccessRole {\n const modeSet = new Set(modes)\n const matchingRule = ACCESS_ROLE_RULES.find(rule =>\n rule.modes.length === modeSet.size &&\n rule.modes.every(mode => modeSet.has(mode)))\n\n return matchingRule?.label ?? 'No Access'\n }\n\n function modesFromRole (role: AccessRole): AccessMode[] {\n return [...(ACCESS_ROLE_RULES.find(rule => rule.label === role)?.modes ?? [])]\n }\n\n function publicRoleFromModes (modes: Iterable<AccessMode>): PublicAccessRole {\n const modeSet = new Set(modes)\n const matchingRule = PUBLIC_ROLE_RULES.find(rule => rule.label !== 'No Access' && rule.modes.every(mode => modeSet.has(mode)))\n\n return matchingRule?.label ?? 'No Access'\n }\n\n function modesFromPublicRole (role: PublicAccessRole): AccessMode[] {\n return [...(PUBLIC_ROLE_RULES.find(rule => rule.label === role)?.modes ?? [])]\n }\n\n function getFetch() {\n const fetcher = store.fetcher as {\n _fetch?: (url: string, init?: RequestInit) => Promise<Response>\n fetch?: (url: string, init?: RequestInit) => Promise<Response>\n } | undefined\n const fetch = fetcher?._fetch ?? fetcher?.fetch\n if (!fetch) {\n throw new Error('Cannot find effective ACL, store has no fetcher')\n }\n return fetch.bind(fetcher)\n }\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 async function findEffectiveAcl(resourceURL: string | NamedNode): Promise<ACLContext> {\n const url = typeof resourceURL === 'string' ? resourceURL : resourceURL.value\n return findEffectiveACL(url, { fetch: getFetch() })\n }\n\n async function findAccessGrants(resourceURL: string | NamedNode): Promise<Authorization[]> {\n const context = await findEffectiveAcl(resourceURL)\n return context.authorizations\n }\n\n function classifyContainerScope(context: ACLContext): ContainerAccessScope {\n return classifyContainerAccessScope(context)\n }\n\n function isProtectedResource(resourceURL: string | NamedNode): boolean {\n const resource = sym(typeof resourceURL === 'string' ? resourceURL : resourceURL.value)\n return resource.value === resource.site().value ||\n (typeof store.holds === 'function' &&\n store.holds(resource, ns.rdf('type'), ns.space('Storage'), resource.doc()))\n }\n\n function subjectMatchesAuthorization(subject: AccessSubject, authorization: Authorization): boolean {\n const predicateByType = {\n agent: 'agent',\n agentGroup: 'agentGroup',\n agentClass: 'agentClass',\n origin: 'origin'\n } as const\n return authorization[predicateByType[subject.type]]?.includes(subject.iri) ?? false\n }\n\n function assertProtectedControlPreserved(context: ACLContext, plan: PatchPlan): void {\n if (!isProtectedResource(context.resource)) {\n return\n }\n\n const deletedAuthorizationIds = new Set(plan.deletes.map(statement => statement.subject.value))\n const insertedAuthorizations = new Map<string, { modes: string[], accessTo: string[] }>()\n for (const statement of plan.inserts) {\n const authorization = insertedAuthorizations.get(statement.subject.value) ?? { modes: [], accessTo: [] }\n if (statement.predicate.value === ACL + 'mode') {\n authorization.modes.push(statement.object.value)\n } else if (statement.predicate.value === ACL + 'accessTo') {\n authorization.accessTo.push(statement.object.value)\n }\n insertedAuthorizations.set(statement.subject.value, authorization)\n }\n\n const survivingControl = !context.inherited && context.authorizations.some(authorization =>\n !deletedAuthorizationIds.has(authorization.id) &&\n authorization.mode.includes('Control') &&\n authorization.accessTo.includes(context.resource)\n ) || [...insertedAuthorizations.values()].some(authorization =>\n authorization.modes.includes(ACL + 'Control') &&\n authorization.accessTo.includes(context.resource)\n )\n\n if (!survivingControl) {\n throw new Error('The protected storage resource must retain at least one Control authorization.')\n }\n }\n\n function withContainerDefaults(context: ACLContext, plan: PatchPlan): PatchPlan {\n if (!new URL(context.resource).pathname.endsWith('/')) {\n return plan\n }\n\n // Materializing an inherited container ACL must not cut off its contents.\n // The upstream resource planner emits accessTo only, even for containers.\n const defaults = plan.inserts\n .filter(statement => statement.predicate.value === ACL + 'accessTo' && statement.object.value === context.resource)\n .filter(statement => !plan.inserts.some(existing => existing.subject.equals(statement.subject) && existing.predicate.value === ACL + 'default' && existing.object.value === context.resource))\n .map(statement => quad(statement.subject, namedNode(ACL + 'default'), statement.object))\n\n return { ...plan, inserts: [...plan.inserts, ...defaults] }\n }\n\n async function planGrant(resourceURL: string | NamedNode, subject: AccessSubject, modes: AccessMode[]): Promise<PatchPlan> {\n const context = await findEffectiveAcl(resourceURL)\n if (context.inherited && new URL(context.resource).pathname.endsWith('/')) {\n const plan = materializeInheritedContainer(context, subject, modes, 'folder')\n assertProtectedControlPreserved(context, plan)\n return plan\n }\n const plan = planAuthorizationGrant(context, subject, modes)\n assertProtectedControlPreserved(context, plan)\n return plan\n }\n\n function assertContainer(context: ACLContext): void {\n if (!new URL(context.resource).pathname.endsWith('/')) {\n throw new Error(`Expected a container URL ending in \"/\": ${context.resource}`)\n }\n }\n\n const subjectKeys = ['agent', 'agentClass', 'agentGroup', 'origin'] as const\n const rdfType = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type'\n const supportedConditionPredicates = new Set([\n rdfType,\n ACL + 'client',\n ACL + 'clientClass',\n ACL + 'clientGroup',\n ACL + 'issuer',\n ACL + 'issuerClass',\n ACL + 'issuerGroup',\n ACL + 'description',\n // Some older ACL contexts expose the condition type as a property key\n // rather than retaining it under rdf:type.\n ACL + 'ClientCondition',\n ACL + 'IssuerCondition'\n ])\n const supportedConditionTypes = new Set([\n ACL + 'ClientCondition',\n ACL + 'IssuerCondition'\n ])\n\n function createAuthorizationIdAllocator(context: ACLContext): (base: string) => string {\n const takenIds = new Set<string>([\n ...(context.dataset ?? []).map(statement => statement.subject.value),\n ...context.authorizations.flatMap(authorization => [\n authorization.id,\n ...(authorization.condition ?? []).map(condition => condition.id)\n ])\n ])\n\n return (base: string): string => {\n let id = base\n let suffix = 1\n while (takenIds.has(id)) {\n id = `${base}-${suffix++}`\n }\n takenIds.add(id)\n return id\n }\n }\n\n function assertSupportedConditions(context: ACLContext): void {\n for (const authorization of context.authorizations) {\n for (const condition of authorization.condition ?? []) {\n const conditionTypes = condition.properties[rdfType] ?? []\n if (conditionTypes.length > 1 ||\n (conditionTypes.length === 1 && !supportedConditionTypes.has(conditionTypes[0]))) {\n throw new Error(`Unsupported ACL condition type on ${condition.id}`)\n }\n for (const predicate of Object.keys(condition.properties)) {\n if (!supportedConditionPredicates.has(predicate)) {\n throw new Error(`Unsupported ACL condition property: ${predicate}`)\n }\n }\n }\n }\n }\n\n function materializeInheritedContainer (\n context: ACLContext,\n subject: AccessSubject,\n modes: AccessMode[] | undefined,\n scope: ContainerAccessScope,\n revoke = false\n ): PatchPlan {\n const inserts: PatchPlan['inserts'] = []\n const subjectKey = subject.type\n const freshId = createAuthorizationIdAllocator(context)\n assertSupportedConditions(context)\n const addRule = (\n authorization: Authorization,\n baseId: string,\n targets: { accessTo: boolean, default: boolean },\n modeOverride?: AccessMode[]\n ) => {\n const subjects = subjectKeys.flatMap(key => authorization[key].map(iri => ({ key, iri })))\n if (!subjects.length || (!targets.accessTo && !targets.default)) return\n const id = freshId(baseId)\n const rule = namedNode(id)\n inserts.push(\n quad(rule, namedNode(rdfType), namedNode(ACL + 'Authorization')),\n ...(targets.accessTo ? [quad(rule, namedNode(ACL + 'accessTo'), namedNode(context.resource))] : []),\n ...(targets.default ? [quad(rule, namedNode(ACL + 'default'), namedNode(context.resource))] : []),\n ...(modeOverride ?? authorization.mode).map(mode => quad(rule, namedNode(ACL + 'mode'), namedNode(`http://www.w3.org/ns/auth/acl#${mode}`))),\n ...subjects.map(({ key, iri }) => quad(rule, namedNode(ACL + key), namedNode(iri))),\n ...(authorization.condition ?? []).flatMap(condition => {\n const conditionId = freshId(`${id}-condition`)\n const conditionNode = namedNode(conditionId)\n const conditionStatements = context.dataset\n .filter(statement => statement.subject.value === condition.id)\n .map(statement => quad(\n conditionNode,\n statement.predicate,\n statement.object\n ))\n return [\n quad(rule, namedNode(ACL + 'condition'), conditionNode),\n ...conditionStatements\n ]\n })\n )\n }\n const withoutSubject = (authorization: Authorization): Authorization => ({\n ...authorization,\n [subjectKey]: authorization[subjectKey].filter(iri => iri !== subject.iri)\n })\n const onlySubject = (authorization: Authorization): Authorization => ({\n ...authorization,\n agent: [], agentClass: [], agentGroup: [], origin: [],\n [subjectKey]: [subject.iri]\n })\n context.authorizations.forEach((authorization, index) => {\n const baseId = `${context.defaultACLResource}#inherited-${index + 1}`\n // Legacy adoptACLDefault parity: an inherited acl:default governs\n // this container itself and its contents, so it is copied as\n // accessTo + default. Parent accessTo-only rules do not apply here.\n const inheritedDefault = (authorization.default?.length ?? 0) > 0\n const targets = {\n accessTo: inheritedDefault || authorization.accessTo.includes(context.resource),\n default: inheritedDefault\n }\n const selected = authorization[subjectKey]?.includes(subject.iri) ?? false\n if (!selected) {\n addRule(authorization, baseId, targets)\n return\n }\n addRule(withoutSubject(authorization), baseId, targets)\n // Keep the subject's inherited access for the scope not being changed.\n addRule(onlySubject(authorization), `${baseId}-retained`, {\n accessTo: targets.accessTo && scope === 'contents',\n default: targets.default && scope === 'folder'\n })\n })\n if (!revoke) {\n const selectedAuthorization = context.authorizations.find(authorization =>\n authorization[subjectKey]?.includes(subject.iri) &&\n (authorization.default?.length ?? 0) > 0)\n const newAuthorization: Authorization = {\n id: `${context.defaultACLResource}#inherited-new-source`,\n blankNode: false,\n accessTo: [], default: [], agent: [], agentClass: [], agentGroup: [], origin: [], mode: [],\n condition: selectedAuthorization?.condition ?? []\n }\n addRule(onlySubject(newAuthorization), `${context.defaultACLResource}#inherited-new`, {\n accessTo: scope !== 'contents',\n default: scope !== 'folder'\n }, modes ?? [])\n }\n return { target: context.defaultACLResource, deletes: [], inserts }\n }\n\n async function planGrantContainer(containerURL: string | NamedNode, subject: AccessSubject, modes: AccessMode[]): Promise<PatchPlan> {\n const context = await findEffectiveAcl(containerURL)\n assertContainer(context)\n const plan = context.inherited\n ? materializeInheritedContainer(context, subject, modes, 'folder')\n : planAuthorizationGrant(context, subject, modes)\n assertProtectedControlPreserved(context, plan)\n return plan\n }\n\n async function planGrantContainerAndContents(containerURL: string | NamedNode, subject: AccessSubject, modes: AccessMode[]): Promise<PatchPlan> {\n const context = await findEffectiveAcl(containerURL)\n assertContainer(context)\n const plan = context.inherited\n ? materializeInheritedContainer(context, subject, modes, 'folder+contents')\n : withContainerDefaults(context, planAuthorizationGrant(context, subject, modes))\n assertProtectedControlPreserved(context, plan)\n return plan\n }\n\n async function planGrantContainerContents(containerURL: string | NamedNode, subject: AccessSubject, modes: AccessMode[]): Promise<PatchPlan> {\n const context = await findEffectiveAcl(containerURL)\n assertContainer(context)\n if (isProtectedResource(context.resource)) {\n throw new Error('Applying access to the contents of a protected storage resource is not allowed.')\n }\n if (context.inherited) return materializeInheritedContainer(context, subject, modes, 'contents')\n const matchingAuthorizations = context.authorizations.filter(authorization =>\n authorization.default?.includes(context.resource) &&\n subjectMatchesAuthorization(subject, authorization))\n\n if (matchingAuthorizations.length) {\n return splitDirectContainerContentsAuthorizations(context, matchingAuthorizations, subject, modes)\n }\n\n const subjectKey = subject.type\n const id = createAuthorizationIdAllocator(context)(`${context.defaultACLResource}#contents-1`)\n const rule = namedNode(id)\n const subjectQuad = quad(rule, namedNode(ACL + subjectKey), namedNode(subject.iri))\n const fresh = [\n quad(rule, namedNode(rdfType), namedNode(ACL + 'Authorization')),\n quad(rule, namedNode(ACL + 'default'), namedNode(context.resource)),\n ...modes.map(mode => quad(rule, namedNode(ACL + 'mode'), namedNode(`http://www.w3.org/ns/auth/acl#${mode}`))),\n subjectQuad\n ]\n\n // A folder-only authorization is unrelated and must remain untouched.\n return { target: context.defaultACLResource, deletes: [], inserts: fresh }\n }\n\n async function planRevokeContainerContents(containerURL: string | NamedNode, subject: AccessSubject): Promise<PatchPlan> {\n const context = await findEffectiveAcl(containerURL)\n assertContainer(context)\n if (isProtectedResource(context.resource)) {\n throw new Error('Removing access from the contents of a protected storage resource is not allowed.')\n }\n\n const defaultPredicate = ACL + 'default'\n if (!context.inherited) {\n const matchingAuthorizations = context.authorizations.filter(authorization =>\n authorization.default?.includes(context.resource) &&\n subjectMatchesAuthorization(subject, authorization))\n\n if (matchingAuthorizations.length) {\n return splitDirectContainerContentsAuthorizations(context, matchingAuthorizations, subject)\n }\n\n const deletes = context.dataset.filter(statement =>\n statement.predicate.value === defaultPredicate &&\n statement.object.value === context.resource &&\n context.authorizations.some(authorization =>\n authorization.id === statement.subject.value &&\n authorization[subject.type].includes(subject.iri)))\n if (!deletes.length) {\n throw new Error(`No default authorization found for ${subject.iri}`)\n }\n return { target: context.defaultACLResource, deletes, inserts: [] }\n }\n\n const hasInheritedDefault = context.authorizations.some(authorization =>\n authorization.default?.includes(context.resource) &&\n subjectMatchesAuthorization(subject, authorization))\n if (!hasInheritedDefault) {\n throw new Error(`No default authorization found for ${subject.iri}`)\n }\n const plan = materializeInheritedContainer(context, subject, undefined, 'contents', true)\n return plan\n }\n\n function splitDirectContainerContentsAuthorizations (\n context: ACLContext,\n authorizations: Authorization[],\n subject: AccessSubject,\n modes?: AccessMode[]\n ): PatchPlan {\n const freshId = createAuthorizationIdAllocator(context)\n const inserts: PatchPlan['inserts'] = []\n const addRule = (\n rule: ReturnType<typeof namedNode>,\n ruleSubjects: Array<{ key: typeof subjectKeys[number], iri: string }>,\n ruleModes: AccessMode[],\n accessTo: string[],\n defaults: string[],\n conditions: string[]\n ) => {\n if (!ruleSubjects.length || (!accessTo.length && !defaults.length)) return\n inserts.push(\n quad(rule, namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), namedNode(ACL + 'Authorization')),\n ...accessTo.map(target => quad(rule, namedNode(ACL + 'accessTo'), namedNode(target))),\n ...defaults.map(target => quad(rule, namedNode(ACL + 'default'), namedNode(target))),\n ...ruleModes.map(mode => quad(rule, namedNode(ACL + 'mode'), namedNode(`http://www.w3.org/ns/auth/acl#${mode}`))),\n ...conditions.map(condition => quad(rule, namedNode(ACL + 'condition'), namedNode(condition))),\n ...ruleSubjects.map(({ key, iri }) => quad(rule, namedNode(ACL + key), namedNode(iri)))\n )\n }\n\n const deletes: PatchPlan['deletes'] = []\n authorizations.forEach((authorization, index) => {\n const subjects = subjectKeys.flatMap(key =>\n authorization[key].map(iri => ({ key, iri }))\n )\n const remainingSubjects = subjects.filter(({ key, iri }) =>\n !(key === subject.type && iri === subject.iri))\n const baseId = `${context.defaultACLResource}#split-${index + 1}`\n\n if (!modes && subjects.length === 1 && remainingSubjects.length === 0) {\n deletes.push(...context.dataset.filter(statement =>\n statement.subject.value === authorization.id &&\n statement.predicate.value === ACL + 'default' &&\n statement.object.value === context.resource))\n return\n }\n\n deletes.push(...context.dataset.filter(statement => statement.subject.value === authorization.id))\n const conditions = (authorization.condition ?? []).map(condition => condition.id)\n addRule(namedNode(freshId(`${context.defaultACLResource}#retained-${index + 1}`)), remainingSubjects, authorization.mode, authorization.accessTo, authorization.default, conditions)\n const retainedDefaults = authorization.default.filter(target => target !== context.resource)\n if (authorization.accessTo.length || retainedDefaults.length) {\n addRule(\n namedNode(freshId(`${baseId}-retained`)),\n [{ key: subject.type, iri: subject.iri }],\n authorization.mode,\n authorization.accessTo,\n retainedDefaults,\n conditions\n )\n }\n if (modes) {\n addRule(\n namedNode(freshId(`${baseId}`)),\n [{ key: subject.type, iri: subject.iri }],\n modes,\n [],\n authorization.default.filter(target => target === context.resource),\n conditions\n )\n }\n })\n\n return {\n target: context.defaultACLResource,\n deletes,\n inserts\n }\n }\n\n async function planRevoke(resourceURL: string | NamedNode, subject: AccessSubject): Promise<PatchPlan> {\n const context = await findEffectiveAcl(resourceURL)\n if (context.inherited && new URL(context.resource).pathname.endsWith('/')) {\n const plan = materializeInheritedContainer(context, subject, undefined, 'folder+contents', true)\n assertProtectedControlPreserved(context, plan)\n return plan\n }\n const plan = withContainerDefaults(context, planAuthorizationRevoke(context, subject))\n assertProtectedControlPreserved(context, plan)\n return plan\n }\n\n async function planPublicRead(resourceURL: string | NamedNode, enabled: boolean): Promise<PatchPlan> {\n const context = await findEffectiveAcl(resourceURL)\n return planAuthorizationPublicRead(context, enabled)\n }\n\n async function resetToDefault(resourceURL: string | NamedNode): Promise<Response> {\n const context = await findEffectiveAcl(resourceURL)\n if (isProtectedResource(context.resource)) {\n throw new Error('The protected storage resource cannot be reset to a default ACL.')\n }\n const response = await getFetch()(context.defaultACLResource, { method: 'DELETE' })\n\n if (!response.ok && response.status !== 404) {\n throw new Error(`Unable to remove ACL ${context.defaultACLResource}: HTTP ${response.status}`)\n }\n\n return response\n }\n\n async function applyPlan(plan: PatchPlan): Promise<Response> {\n return applyAuthorizationPlan(plan, { fetch: getFetch() })\n }\n\n async function classifyAccessControlSubject(principle: string) {\n return accessControlSubjects.classifyAccessControlSubject(store, principle)\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 findEffectiveAcl,\n findAccessGrants,\n classifyContainerScope,\n isProtectedResource,\n roleFromModes,\n modesFromRole,\n publicRoleFromModes,\n modesFromPublicRole,\n planGrant,\n planGrantContainer,\n planGrantContainerAndContents,\n planGrantContainerContents,\n planRevokeContainerContents,\n planRevoke,\n planPublicRead,\n resetToDefault,\n applyPlan,\n classifyAccessControlSubject,\n setACLUserPublic,\n genACLText,\n Authenticated,\n Public,\n PUBLIC_ACCESS_ROLES\n }\n}"],"mappings":"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"}
1
+ {"version":3,"file":"aclLogic.cjs.js","names":["ACL","sym","ns","namespace","findEffectiveACL","quad","namedNode","planAuthorizationGrant","planAuthorizationRevoke","planAuthorizationPublicRead","applyAuthorizationPlan","classifyAccessControlSubject","graph","Namespace","serialize","require_ns","require_accessControlSubjects","rdflib","_dokieli_web_access_control","ACCESS_ROLES","PUBLIC_ACCESS_ROLES","WRITE_LOCKED_OWNER_ROLE","classifyAuthorizationScope","inheritedDefault","inherited","authorization","hasAccessTo","resource","hasDefault","filterAuthorizationsByContainerScope","authorizations","scope","classifyContainerAccessScope","analyzeContainerAccessScope","context","scopes","entries","statement","entry","distinctScopes","ACL_LINK","createAclLogic","ns$1","ACCESS_ROLE_RULES","PUBLIC_ROLE_RULES","roleFromModes","modeSet","modes","rule","mode","modesFromRole","role","publicRoleFromModes","modesFromPublicRole","getFetch","fetcher","store","fetch","findAclDocUrl","url","docNode","findEffectiveAcl","resourceURL","findAccessGrants","classifyContainerScope","isProtectedResource","subjectMatchesAuthorization","subject","assertProtectedControlPreserved","deletedAuthorizationIds","plan","insertedAuthorizations","withContainerDefaults","defaults","existing","planGrant","materializeInheritedContainer","assertContainer","subjectKeys","rdfType","supportedConditionPredicates","supportedConditionTypes","createAuthorizationIdAllocator","takenIds","condition","id","base","suffix","assertSupportedConditions","conditionTypes","predicate","inserts","subjectKey","freshId","addRule","subjects","key","targets","baseId","modeOverride","iri","conditionId","conditionNode","conditionStatements","withoutSubject","onlySubject","index","revoke","selectedAuthorization","planGrantContainer","containerURL","planGrantContainerAndContents","planGrantContainerContents","matchingAuthorizations","splitDirectContainerContentsAuthorizations","subjectQuad","fresh","planRevokeContainerContents","defaultPredicate","deletes","ruleSubjects","accessTo","target","ruleModes","conditions","remainingSubjects","retainedDefaults","planRevoke","planPublicRead","enabled","resetToDefault","response","applyPlan","classifyAccessControlSubject$1","principle","setACLUserPublic","aclDoc","docURI","fetchACLRel","err","aclText","genACLText","me","options","result","optPublic","g","auth","a","aclURI","acl","doc","p"],"sources":["../../src/acl/aclLogic.ts"],"sourcesContent":["import { ACL, namedNode, quad, applyPlan as applyAuthorizationPlan, Authenticated, findEffectiveACL, planGrant as planAuthorizationGrant, planPublicRead as planAuthorizationPublicRead, planRevoke as planAuthorizationRevoke, Public, type AccessMode, type AccessSubject, type ACLContext, type Authorization, type PatchPlan } from '@dokieli/web-access-control'\nimport { graph, NamedNode, Namespace, serialize, sym } from 'rdflib'\nimport type { AclLogic } from '../types'\nimport { ns as namespace } from '../util/ns'\nimport * as accessControlSubjects from './accessControlSubjects'\n\nexport const ACCESS_ROLES = ['Owner', 'Editor', 'No Access', 'Viewer', 'Poster', 'Submitter'] as const\nexport const PUBLIC_ACCESS_ROLES = ['No Access', 'Viewer'] as const\n/**\n * A Control grant without Write is the legacy \"write locked\" owner grant.\n *\n * It is intentionally not part of ACCESS_ROLES yet: that list is consumed by\n * the existing UI, whose selector will be updated in a later change.\n */\nexport const WRITE_LOCKED_OWNER_ROLE = 'Owner (write locked)' as const\nexport { Authenticated, Public } from '@dokieli/web-access-control'\n\nexport type AccessRole = typeof ACCESS_ROLES[number] | typeof WRITE_LOCKED_OWNER_ROLE\nexport type PublicAccessRole = typeof PUBLIC_ACCESS_ROLES[number]\nexport type ContainerAccessScope = 'folder+contents' | 'folder' | 'contents'\nexport interface ContainerAccessScopeResult {\n distinctScopes: ContainerAccessScope[]\n primaryScope: ContainerAccessScope\n mixed: boolean\n}\nexport function classifyAuthorizationScope (\n resource: string,\n authorization: Authorization,\n inherited = false\n): ContainerAccessScope | undefined {\n // Effective ACL discovery keeps inherited `acl:default` targets on the\n // parent container. They govern both this container and its contents\n // (legacy adoptACLDefault copies them as accessTo + default).\n const inheritedDefault = inherited && (authorization.default?.length ?? 0) > 0\n const hasAccessTo = inheritedDefault || (authorization.accessTo?.includes(resource) ?? false)\n const hasDefault = inheritedDefault || (authorization.default?.includes(resource) ?? false)\n if (hasAccessTo && hasDefault) return 'folder+contents'\n if (hasAccessTo) return 'folder'\n if (hasDefault) return 'contents'\n return undefined\n}\n\nexport function filterAuthorizationsByContainerScope (\n resource: string,\n authorizations: Authorization[],\n scope: ContainerAccessScope,\n inherited = false\n): Authorization[] {\n return authorizations.filter(authorization =>\n classifyAuthorizationScope(resource, authorization, inherited) === scope\n )\n}\n\n/**\n * Classify the direct ACL predicates for a container. Mixed grants are\n * conservatively treated as covering both scopes.\n */\nexport function classifyContainerAccessScope (context: ACLContext): ContainerAccessScope {\n return analyzeContainerAccessScope(context).primaryScope\n}\n\nexport function analyzeContainerAccessScope (context: ACLContext): ContainerAccessScopeResult {\n const scopes = new Set<ContainerAccessScope>()\n for (const authorization of context.authorizations ?? []) {\n const scope = classifyAuthorizationScope(context.resource, authorization, context.inherited)\n if (scope) scopes.add(scope)\n }\n // Older callers may provide only the graph. Preserve their classification\n // while keeping the authorization-entry semantics for parsed contexts.\n if (!scopes.size) {\n const entries = new Map<string, { accessTo: boolean, default: boolean }>()\n for (const statement of context.dataset ?? []) {\n if (statement.object.value !== context.resource) continue\n if (statement.predicate.value !== ACL + 'accessTo' && statement.predicate.value !== ACL + 'default') continue\n const entry = entries.get(statement.subject.value) ?? { accessTo: false, default: false }\n entry.accessTo ||= statement.predicate.value === ACL + 'accessTo'\n entry.default ||= statement.predicate.value === ACL + 'default'\n entries.set(statement.subject.value, entry)\n }\n for (const entry of entries.values()) {\n if (entry.accessTo && entry.default) scopes.add('folder+contents')\n else if (entry.accessTo) scopes.add('folder')\n else if (entry.default) scopes.add('contents')\n }\n }\n const distinctScopes = [...scopes]\n const primaryScope = distinctScopes.includes('folder+contents')\n ? 'folder+contents'\n : distinctScopes.includes('contents')\n ? 'contents'\n : distinctScopes.includes('folder')\n ? 'folder'\n : 'folder+contents'\n return { distinctScopes, primaryScope, mixed: distinctScopes.length > 1 }\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 const ACCESS_ROLE_RULES: Array<{ label: AccessRole, modes: AccessMode[] }> = [\n { label: 'Owner', modes: ['Read', 'Write', 'Control'] },\n { label: WRITE_LOCKED_OWNER_ROLE, modes: ['Read', 'Control'] },\n { label: 'Editor', modes: ['Read', 'Write'] },\n { label: 'Poster', modes: ['Append', 'Read'] },\n { label: 'Submitter', modes: ['Append'] },\n { label: 'Viewer', modes: ['Read'] },\n { label: 'No Access', modes: [] }\n ]\n const PUBLIC_ROLE_RULES: Array<{ label: PublicAccessRole, modes: AccessMode[] }> = [\n { label: 'Viewer', modes: ['Read'] },\n { label: 'No Access', modes: [] }\n ]\n\n function roleFromModes (modes: Iterable<AccessMode>): AccessRole {\n const modeSet = new Set(modes)\n const matchingRule = ACCESS_ROLE_RULES.find(rule =>\n rule.modes.length === modeSet.size &&\n rule.modes.every(mode => modeSet.has(mode)))\n\n return matchingRule?.label ?? 'No Access'\n }\n\n function modesFromRole (role: AccessRole): AccessMode[] {\n return [...(ACCESS_ROLE_RULES.find(rule => rule.label === role)?.modes ?? [])]\n }\n\n function publicRoleFromModes (modes: Iterable<AccessMode>): PublicAccessRole {\n const modeSet = new Set(modes)\n const matchingRule = PUBLIC_ROLE_RULES.find(rule => rule.label !== 'No Access' && rule.modes.every(mode => modeSet.has(mode)))\n\n return matchingRule?.label ?? 'No Access'\n }\n\n function modesFromPublicRole (role: PublicAccessRole): AccessMode[] {\n return [...(PUBLIC_ROLE_RULES.find(rule => rule.label === role)?.modes ?? [])]\n }\n\n function getFetch() {\n const fetcher = store.fetcher as {\n _fetch?: (url: string, init?: RequestInit) => Promise<Response>\n fetch?: (url: string, init?: RequestInit) => Promise<Response>\n } | undefined\n const fetch = fetcher?._fetch ?? fetcher?.fetch\n if (!fetch) {\n throw new Error('Cannot find effective ACL, store has no fetcher')\n }\n return fetch.bind(fetcher)\n }\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 async function findEffectiveAcl(resourceURL: string | NamedNode): Promise<ACLContext> {\n const url = typeof resourceURL === 'string' ? resourceURL : resourceURL.value\n return findEffectiveACL(url, { fetch: getFetch() })\n }\n\n async function findAccessGrants(resourceURL: string | NamedNode): Promise<Authorization[]> {\n const context = await findEffectiveAcl(resourceURL)\n return context.authorizations\n }\n\n function classifyContainerScope(context: ACLContext): ContainerAccessScope {\n return classifyContainerAccessScope(context)\n }\n\n function isProtectedResource(resourceURL: string | NamedNode): boolean {\n const resource = sym(typeof resourceURL === 'string' ? resourceURL : resourceURL.value)\n return resource.value === resource.site().value ||\n (typeof store.holds === 'function' &&\n store.holds(resource, ns.rdf('type'), ns.space('Storage'), resource.doc()))\n }\n\n function subjectMatchesAuthorization(subject: AccessSubject, authorization: Authorization): boolean {\n const predicateByType = {\n agent: 'agent',\n agentGroup: 'agentGroup',\n agentClass: 'agentClass',\n origin: 'origin'\n } as const\n return authorization[predicateByType[subject.type]]?.includes(subject.iri) ?? false\n }\n\n function assertProtectedControlPreserved(context: ACLContext, plan: PatchPlan): void {\n if (!isProtectedResource(context.resource)) {\n return\n }\n\n const deletedAuthorizationIds = new Set(plan.deletes.map(statement => statement.subject.value))\n const insertedAuthorizations = new Map<string, { modes: string[], accessTo: string[] }>()\n for (const statement of plan.inserts) {\n const authorization = insertedAuthorizations.get(statement.subject.value) ?? { modes: [], accessTo: [] }\n if (statement.predicate.value === ACL + 'mode') {\n authorization.modes.push(statement.object.value)\n } else if (statement.predicate.value === ACL + 'accessTo') {\n authorization.accessTo.push(statement.object.value)\n }\n insertedAuthorizations.set(statement.subject.value, authorization)\n }\n\n const survivingControl = !context.inherited && context.authorizations.some(authorization =>\n !deletedAuthorizationIds.has(authorization.id) &&\n authorization.mode.includes('Control') &&\n authorization.accessTo.includes(context.resource)\n ) || [...insertedAuthorizations.values()].some(authorization =>\n authorization.modes.includes(ACL + 'Control') &&\n authorization.accessTo.includes(context.resource)\n )\n\n if (!survivingControl) {\n throw new Error('The protected storage resource must retain at least one Control authorization.')\n }\n }\n\n function withContainerDefaults(context: ACLContext, plan: PatchPlan): PatchPlan {\n if (!new URL(context.resource).pathname.endsWith('/')) {\n return plan\n }\n\n // Materializing an inherited container ACL must not cut off its contents.\n // The upstream resource planner emits accessTo only, even for containers.\n const defaults = plan.inserts\n .filter(statement => statement.predicate.value === ACL + 'accessTo' && statement.object.value === context.resource)\n .filter(statement => !plan.inserts.some(existing => existing.subject.equals(statement.subject) && existing.predicate.value === ACL + 'default' && existing.object.value === context.resource))\n .map(statement => quad(statement.subject, namedNode(ACL + 'default'), statement.object))\n\n return { ...plan, inserts: [...plan.inserts, ...defaults] }\n }\n\n async function planGrant(resourceURL: string | NamedNode, subject: AccessSubject, modes: AccessMode[]): Promise<PatchPlan> {\n const context = await findEffectiveAcl(resourceURL)\n if (context.inherited && new URL(context.resource).pathname.endsWith('/')) {\n const plan = materializeInheritedContainer(context, subject, modes, 'folder')\n assertProtectedControlPreserved(context, plan)\n return plan\n }\n const plan = planAuthorizationGrant(context, subject, modes)\n assertProtectedControlPreserved(context, plan)\n return plan\n }\n\n function assertContainer(context: ACLContext): void {\n if (!new URL(context.resource).pathname.endsWith('/')) {\n throw new Error(`Expected a container URL ending in \"/\": ${context.resource}`)\n }\n }\n\n const subjectKeys = ['agent', 'agentClass', 'agentGroup', 'origin'] as const\n const rdfType = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type'\n const supportedConditionPredicates = new Set([\n rdfType,\n ACL + 'client',\n ACL + 'clientClass',\n ACL + 'clientGroup',\n ACL + 'issuer',\n ACL + 'issuerClass',\n ACL + 'issuerGroup',\n ACL + 'description',\n // Some older ACL contexts expose the condition type as a property key\n // rather than retaining it under rdf:type.\n ACL + 'ClientCondition',\n ACL + 'IssuerCondition'\n ])\n const supportedConditionTypes = new Set([\n ACL + 'ClientCondition',\n ACL + 'IssuerCondition'\n ])\n\n function createAuthorizationIdAllocator(context: ACLContext): (base: string) => string {\n const takenIds = new Set<string>([\n ...(context.dataset ?? []).map(statement => statement.subject.value),\n ...context.authorizations.flatMap(authorization => [\n authorization.id,\n ...(authorization.condition ?? []).map(condition => condition.id)\n ])\n ])\n\n return (base: string): string => {\n let id = base\n let suffix = 1\n while (takenIds.has(id)) {\n id = `${base}-${suffix++}`\n }\n takenIds.add(id)\n return id\n }\n }\n\n function assertSupportedConditions(context: ACLContext): void {\n for (const authorization of context.authorizations) {\n for (const condition of authorization.condition ?? []) {\n const conditionTypes = condition.properties[rdfType] ?? []\n if (conditionTypes.length > 1 ||\n (conditionTypes.length === 1 && !supportedConditionTypes.has(conditionTypes[0]))) {\n throw new Error(`Unsupported ACL condition type on ${condition.id}`)\n }\n for (const predicate of Object.keys(condition.properties)) {\n if (!supportedConditionPredicates.has(predicate)) {\n throw new Error(`Unsupported ACL condition property: ${predicate}`)\n }\n }\n }\n }\n }\n\n function materializeInheritedContainer (\n context: ACLContext,\n subject: AccessSubject,\n modes: AccessMode[] | undefined,\n scope: ContainerAccessScope,\n revoke = false\n ): PatchPlan {\n const inserts: PatchPlan['inserts'] = []\n const subjectKey = subject.type\n const freshId = createAuthorizationIdAllocator(context)\n assertSupportedConditions(context)\n const addRule = (\n authorization: Authorization,\n baseId: string,\n targets: { accessTo: boolean, default: boolean },\n modeOverride?: AccessMode[]\n ) => {\n const subjects = subjectKeys.flatMap(key => authorization[key].map(iri => ({ key, iri })))\n if (!subjects.length || (!targets.accessTo && !targets.default)) return\n const id = freshId(baseId)\n const rule = namedNode(id)\n inserts.push(\n quad(rule, namedNode(rdfType), namedNode(ACL + 'Authorization')),\n ...(targets.accessTo ? [quad(rule, namedNode(ACL + 'accessTo'), namedNode(context.resource))] : []),\n ...(targets.default ? [quad(rule, namedNode(ACL + 'default'), namedNode(context.resource))] : []),\n ...(modeOverride ?? authorization.mode).map(mode => quad(rule, namedNode(ACL + 'mode'), namedNode(`http://www.w3.org/ns/auth/acl#${mode}`))),\n ...subjects.map(({ key, iri }) => quad(rule, namedNode(ACL + key), namedNode(iri))),\n ...(authorization.condition ?? []).flatMap(condition => {\n const conditionId = freshId(`${id}-condition`)\n const conditionNode = namedNode(conditionId)\n const conditionStatements = context.dataset\n .filter(statement => statement.subject.value === condition.id)\n .map(statement => quad(\n conditionNode,\n statement.predicate,\n statement.object\n ))\n return [\n quad(rule, namedNode(ACL + 'condition'), conditionNode),\n ...conditionStatements\n ]\n })\n )\n }\n const withoutSubject = (authorization: Authorization): Authorization => ({\n ...authorization,\n [subjectKey]: authorization[subjectKey].filter(iri => iri !== subject.iri)\n })\n const onlySubject = (authorization: Authorization): Authorization => ({\n ...authorization,\n agent: [], agentClass: [], agentGroup: [], origin: [],\n [subjectKey]: [subject.iri]\n })\n context.authorizations.forEach((authorization, index) => {\n const baseId = `${context.defaultACLResource}#inherited-${index + 1}`\n // Legacy adoptACLDefault parity: an inherited acl:default governs\n // this container itself and its contents, so it is copied as\n // accessTo + default. Parent accessTo-only rules do not apply here.\n const inheritedDefault = (authorization.default?.length ?? 0) > 0\n const targets = {\n accessTo: inheritedDefault || authorization.accessTo.includes(context.resource),\n default: inheritedDefault\n }\n const selected = authorization[subjectKey]?.includes(subject.iri) ?? false\n if (!selected) {\n addRule(authorization, baseId, targets)\n return\n }\n addRule(withoutSubject(authorization), baseId, targets)\n // Keep the subject's inherited access for the scope not being changed.\n addRule(onlySubject(authorization), `${baseId}-retained`, {\n accessTo: targets.accessTo && scope === 'contents',\n default: targets.default && scope === 'folder'\n })\n })\n if (!revoke) {\n const selectedAuthorization = context.authorizations.find(authorization =>\n authorization[subjectKey]?.includes(subject.iri) &&\n (authorization.default?.length ?? 0) > 0)\n const newAuthorization: Authorization = {\n id: `${context.defaultACLResource}#inherited-new-source`,\n blankNode: false,\n accessTo: [], default: [], agent: [], agentClass: [], agentGroup: [], origin: [], mode: [],\n condition: selectedAuthorization?.condition ?? []\n }\n addRule(onlySubject(newAuthorization), `${context.defaultACLResource}#inherited-new`, {\n accessTo: scope !== 'contents',\n default: scope !== 'folder'\n }, modes ?? [])\n }\n return { target: context.defaultACLResource, deletes: [], inserts }\n }\n\n async function planGrantContainer(containerURL: string | NamedNode, subject: AccessSubject, modes: AccessMode[]): Promise<PatchPlan> {\n const context = await findEffectiveAcl(containerURL)\n assertContainer(context)\n const plan = context.inherited\n ? materializeInheritedContainer(context, subject, modes, 'folder')\n : planAuthorizationGrant(context, subject, modes)\n assertProtectedControlPreserved(context, plan)\n return plan\n }\n\n async function planGrantContainerAndContents(containerURL: string | NamedNode, subject: AccessSubject, modes: AccessMode[]): Promise<PatchPlan> {\n const context = await findEffectiveAcl(containerURL)\n assertContainer(context)\n const plan = context.inherited\n ? materializeInheritedContainer(context, subject, modes, 'folder+contents')\n : withContainerDefaults(context, planAuthorizationGrant(context, subject, modes))\n assertProtectedControlPreserved(context, plan)\n return plan\n }\n\n async function planGrantContainerContents(containerURL: string | NamedNode, subject: AccessSubject, modes: AccessMode[]): Promise<PatchPlan> {\n const context = await findEffectiveAcl(containerURL)\n assertContainer(context)\n if (isProtectedResource(context.resource)) {\n throw new Error('Applying access to the contents of a protected storage resource is not allowed.')\n }\n if (context.inherited) return materializeInheritedContainer(context, subject, modes, 'contents')\n const matchingAuthorizations = context.authorizations.filter(authorization =>\n authorization.default?.includes(context.resource) &&\n subjectMatchesAuthorization(subject, authorization))\n\n if (matchingAuthorizations.length) {\n return splitDirectContainerContentsAuthorizations(context, matchingAuthorizations, subject, modes)\n }\n\n const subjectKey = subject.type\n const id = createAuthorizationIdAllocator(context)(`${context.defaultACLResource}#contents-1`)\n const rule = namedNode(id)\n const subjectQuad = quad(rule, namedNode(ACL + subjectKey), namedNode(subject.iri))\n const fresh = [\n quad(rule, namedNode(rdfType), namedNode(ACL + 'Authorization')),\n quad(rule, namedNode(ACL + 'default'), namedNode(context.resource)),\n ...modes.map(mode => quad(rule, namedNode(ACL + 'mode'), namedNode(`http://www.w3.org/ns/auth/acl#${mode}`))),\n subjectQuad\n ]\n\n // A folder-only authorization is unrelated and must remain untouched.\n return { target: context.defaultACLResource, deletes: [], inserts: fresh }\n }\n\n async function planRevokeContainerContents(containerURL: string | NamedNode, subject: AccessSubject): Promise<PatchPlan> {\n const context = await findEffectiveAcl(containerURL)\n assertContainer(context)\n if (isProtectedResource(context.resource)) {\n throw new Error('Removing access from the contents of a protected storage resource is not allowed.')\n }\n\n const defaultPredicate = ACL + 'default'\n if (!context.inherited) {\n const matchingAuthorizations = context.authorizations.filter(authorization =>\n authorization.default?.includes(context.resource) &&\n subjectMatchesAuthorization(subject, authorization))\n\n if (matchingAuthorizations.length) {\n return splitDirectContainerContentsAuthorizations(context, matchingAuthorizations, subject)\n }\n\n const deletes = context.dataset.filter(statement =>\n statement.predicate.value === defaultPredicate &&\n statement.object.value === context.resource &&\n context.authorizations.some(authorization =>\n authorization.id === statement.subject.value &&\n authorization[subject.type].includes(subject.iri)))\n if (!deletes.length) {\n throw new Error(`No default authorization found for ${subject.iri}`)\n }\n return { target: context.defaultACLResource, deletes, inserts: [] }\n }\n\n const hasInheritedDefault = context.authorizations.some(authorization =>\n authorization.default?.includes(context.resource) &&\n subjectMatchesAuthorization(subject, authorization))\n if (!hasInheritedDefault) {\n throw new Error(`No default authorization found for ${subject.iri}`)\n }\n const plan = materializeInheritedContainer(context, subject, undefined, 'contents', true)\n return plan\n }\n\n function splitDirectContainerContentsAuthorizations (\n context: ACLContext,\n authorizations: Authorization[],\n subject: AccessSubject,\n modes?: AccessMode[]\n ): PatchPlan {\n const freshId = createAuthorizationIdAllocator(context)\n const inserts: PatchPlan['inserts'] = []\n const addRule = (\n rule: ReturnType<typeof namedNode>,\n ruleSubjects: Array<{ key: typeof subjectKeys[number], iri: string }>,\n ruleModes: AccessMode[],\n accessTo: string[],\n defaults: string[],\n conditions: string[]\n ) => {\n if (!ruleSubjects.length || (!accessTo.length && !defaults.length)) return\n inserts.push(\n quad(rule, namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), namedNode(ACL + 'Authorization')),\n ...accessTo.map(target => quad(rule, namedNode(ACL + 'accessTo'), namedNode(target))),\n ...defaults.map(target => quad(rule, namedNode(ACL + 'default'), namedNode(target))),\n ...ruleModes.map(mode => quad(rule, namedNode(ACL + 'mode'), namedNode(`http://www.w3.org/ns/auth/acl#${mode}`))),\n ...conditions.map(condition => quad(rule, namedNode(ACL + 'condition'), namedNode(condition))),\n ...ruleSubjects.map(({ key, iri }) => quad(rule, namedNode(ACL + key), namedNode(iri)))\n )\n }\n\n const deletes: PatchPlan['deletes'] = []\n authorizations.forEach((authorization, index) => {\n const subjects = subjectKeys.flatMap(key =>\n authorization[key].map(iri => ({ key, iri }))\n )\n const remainingSubjects = subjects.filter(({ key, iri }) =>\n !(key === subject.type && iri === subject.iri))\n const baseId = `${context.defaultACLResource}#split-${index + 1}`\n\n if (!modes && subjects.length === 1 && remainingSubjects.length === 0) {\n deletes.push(...context.dataset.filter(statement =>\n statement.subject.value === authorization.id &&\n statement.predicate.value === ACL + 'default' &&\n statement.object.value === context.resource))\n return\n }\n\n deletes.push(...context.dataset.filter(statement => statement.subject.value === authorization.id))\n const conditions = (authorization.condition ?? []).map(condition => condition.id)\n addRule(namedNode(freshId(`${context.defaultACLResource}#retained-${index + 1}`)), remainingSubjects, authorization.mode, authorization.accessTo, authorization.default, conditions)\n const retainedDefaults = authorization.default.filter(target => target !== context.resource)\n if (authorization.accessTo.length || retainedDefaults.length) {\n addRule(\n namedNode(freshId(`${baseId}-retained`)),\n [{ key: subject.type, iri: subject.iri }],\n authorization.mode,\n authorization.accessTo,\n retainedDefaults,\n conditions\n )\n }\n if (modes) {\n addRule(\n namedNode(freshId(`${baseId}`)),\n [{ key: subject.type, iri: subject.iri }],\n modes,\n [],\n authorization.default.filter(target => target === context.resource),\n conditions\n )\n }\n })\n\n return {\n target: context.defaultACLResource,\n deletes,\n inserts\n }\n }\n\n async function planRevoke(resourceURL: string | NamedNode, subject: AccessSubject): Promise<PatchPlan> {\n const context = await findEffectiveAcl(resourceURL)\n if (context.inherited && new URL(context.resource).pathname.endsWith('/')) {\n const plan = materializeInheritedContainer(context, subject, undefined, 'folder+contents', true)\n assertProtectedControlPreserved(context, plan)\n return plan\n }\n const plan = withContainerDefaults(context, planAuthorizationRevoke(context, subject))\n assertProtectedControlPreserved(context, plan)\n return plan\n }\n\n async function planPublicRead(resourceURL: string | NamedNode, enabled: boolean): Promise<PatchPlan> {\n const context = await findEffectiveAcl(resourceURL)\n return planAuthorizationPublicRead(context, enabled)\n }\n\n async function resetToDefault(resourceURL: string | NamedNode): Promise<Response> {\n const context = await findEffectiveAcl(resourceURL)\n if (isProtectedResource(context.resource)) {\n throw new Error('The protected storage resource cannot be reset to a default ACL.')\n }\n const response = await getFetch()(context.defaultACLResource, { method: 'DELETE' })\n\n if (!response.ok && response.status !== 404) {\n throw new Error(`Unable to remove ACL ${context.defaultACLResource}: HTTP ${response.status}`)\n }\n\n return response\n }\n\n async function applyPlan(plan: PatchPlan): Promise<Response> {\n return applyAuthorizationPlan(plan, { fetch: getFetch() })\n }\n\n async function classifyAccessControlSubject(principle: string) {\n return accessControlSubjects.classifyAccessControlSubject(store, principle)\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 findEffectiveAcl,\n findAccessGrants,\n classifyContainerScope,\n isProtectedResource,\n roleFromModes,\n modesFromRole,\n publicRoleFromModes,\n modesFromPublicRole,\n planGrant,\n planGrantContainer,\n planGrantContainerAndContents,\n planGrantContainerContents,\n planRevokeContainerContents,\n planRevoke,\n planPublicRead,\n resetToDefault,\n applyPlan,\n classifyAccessControlSubject,\n setACLUserPublic,\n genACLText,\n Authenticated,\n Public,\n PUBLIC_ACCESS_ROLES\n }\n}"],"mappings":"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"}
@@ -231,14 +231,10 @@ function E(c) {
231
231
  accessTo: o || n.accessTo.includes(e.resource),
232
232
  default: o
233
233
  };
234
- if (!(n[s]?.includes(t.iri) ?? !1)) {
235
- l(n, a, c);
236
- return;
237
- }
238
- l(u(n), a, c), l(d(n), `${a}-retained`, {
234
+ n[s]?.includes(t.iri) ?? !1 ? (l(u(n), a, c), l(d(n), `${a}-retained`, {
239
235
  accessTo: c.accessTo && r === "contents",
240
236
  default: c.default && r === "folder"
241
- });
237
+ })) : l(n, a, c);
242
238
  }), !i) {
243
239
  let i = e.authorizations.find((e) => e[s]?.includes(t.iri) && (e.default?.length ?? 0) > 0);
244
240
  l(d({