solid-logic 4.0.8-3 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/2729812e0bfc062ee77a.js +1 -0
- package/dist/a9c30b64ceaae48b72f0.js +2045 -0
- package/dist/acl/aclLogic.d.ts +5 -0
- package/dist/acl/aclLogic.d.ts.map +1 -0
- package/dist/authSession/authSession.d.ts +42 -0
- package/dist/authSession/authSession.d.ts.map +1 -0
- package/dist/authSession/events.d.ts +24 -0
- package/dist/authSession/events.d.ts.map +1 -0
- package/dist/authSession/issuer.d.ts +8 -0
- package/dist/authSession/issuer.d.ts.map +1 -0
- package/dist/authSession/session.d.ts +45 -0
- package/dist/authSession/session.d.ts.map +1 -0
- package/dist/authn/SolidAuthnLogic.d.ts +42 -0
- package/dist/authn/SolidAuthnLogic.d.ts.map +1 -0
- package/dist/authn/authUtil.d.ts +17 -0
- package/dist/authn/authUtil.d.ts.map +1 -0
- package/dist/authn/serverLogout.d.ts +6 -0
- package/dist/authn/serverLogout.d.ts.map +1 -0
- package/dist/chat/chatLogic.d.ts +3 -0
- package/dist/chat/chatLogic.d.ts.map +1 -0
- package/dist/inbox/inboxLogic.d.ts +3 -0
- package/dist/inbox/inboxLogic.d.ts.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/issuer/issuerLogic.d.ts +8 -0
- package/dist/issuer/issuerLogic.d.ts.map +1 -0
- package/dist/logic/CustomError.d.ts +21 -0
- package/dist/logic/CustomError.d.ts.map +1 -0
- package/dist/logic/solidLogic.d.ts +6 -0
- package/dist/logic/solidLogic.d.ts.map +1 -0
- package/dist/logic/solidLogicSingleton.d.ts +4 -0
- package/dist/logic/solidLogicSingleton.d.ts.map +1 -0
- package/dist/profile/profileAclDocuments.d.ts +2 -0
- package/dist/profile/profileAclDocuments.d.ts.map +1 -0
- package/dist/profile/profileDocuments.d.ts +2 -0
- package/dist/profile/profileDocuments.d.ts.map +1 -0
- package/dist/profile/profileLogic.d.ts +3 -0
- package/dist/profile/profileLogic.d.ts.map +1 -0
- package/dist/solid-logic.esm.js +2358 -0
- package/dist/solid-logic.esm.js.map +1 -0
- package/dist/solid-logic.esm.min.js +2 -0
- package/dist/solid-logic.esm.min.js.map +1 -0
- package/dist/solid-logic.js +7548 -0
- package/dist/solid-logic.js.map +1 -0
- package/dist/solid-logic.min.js +2 -0
- package/dist/solid-logic.min.js.map +1 -0
- package/dist/typeIndex/typeIndexAclDocuments.d.ts +2 -0
- package/dist/typeIndex/typeIndexAclDocuments.d.ts.map +1 -0
- package/dist/typeIndex/typeIndexDocuments.d.ts +3 -0
- package/dist/typeIndex/typeIndexDocuments.d.ts.map +1 -0
- package/dist/typeIndex/typeIndexLogic.d.ts +3 -0
- package/dist/typeIndex/typeIndexLogic.d.ts.map +1 -0
- package/dist/types.d.ts +113 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/util/containerLogic.d.ts +11 -0
- package/dist/util/containerLogic.d.ts.map +1 -0
- package/dist/util/debug.d.ts +5 -0
- package/dist/util/debug.d.ts.map +1 -0
- package/dist/util/ns.d.ts +2 -0
- package/dist/util/ns.d.ts.map +1 -0
- package/dist/util/utilityLogic.d.ts +17 -0
- package/dist/util/utilityLogic.d.ts.map +1 -0
- package/dist/util/utils.d.ts +8 -0
- package/dist/util/utils.d.ts.map +1 -0
- package/package.json +33 -27
- package/dist/_virtual/_rolldown/runtime.cjs.js +0 -1
- package/dist/acl/aclLogic.cjs.js +0 -2
- package/dist/acl/aclLogic.cjs.js.map +0 -1
- package/dist/acl/aclLogic.esm.js +0 -56
- package/dist/acl/aclLogic.esm.js.map +0 -1
- package/dist/authSession/authSession.cjs.js +0 -2
- package/dist/authSession/authSession.cjs.js.map +0 -1
- package/dist/authSession/authSession.esm.js +0 -22
- package/dist/authSession/authSession.esm.js.map +0 -1
- package/dist/authSession/events.cjs.js +0 -2
- package/dist/authSession/events.cjs.js.map +0 -1
- package/dist/authSession/events.esm.js +0 -19
- package/dist/authSession/events.esm.js.map +0 -1
- package/dist/authSession/issuer.cjs.js +0 -2
- package/dist/authSession/issuer.cjs.js.map +0 -1
- package/dist/authSession/issuer.esm.js +0 -18
- package/dist/authSession/issuer.esm.js.map +0 -1
- package/dist/authSession/session.cjs.js +0 -2
- package/dist/authSession/session.cjs.js.map +0 -1
- package/dist/authSession/session.esm.js +0 -102
- package/dist/authSession/session.esm.js.map +0 -1
- package/dist/authn/SolidAuthnLogic.cjs.js +0 -2
- package/dist/authn/SolidAuthnLogic.cjs.js.map +0 -1
- package/dist/authn/SolidAuthnLogic.esm.js +0 -116
- package/dist/authn/SolidAuthnLogic.esm.js.map +0 -1
- package/dist/authn/authUtil.cjs.js +0 -2
- package/dist/authn/authUtil.cjs.js.map +0 -1
- package/dist/authn/authUtil.esm.js +0 -33
- package/dist/authn/authUtil.esm.js.map +0 -1
- package/dist/authn/serverLogout.cjs.js +0 -2
- package/dist/authn/serverLogout.cjs.js.map +0 -1
- package/dist/authn/serverLogout.esm.js +0 -25
- package/dist/authn/serverLogout.esm.js.map +0 -1
- package/dist/chat/chatLogic.cjs.js +0 -21
- package/dist/chat/chatLogic.cjs.js.map +0 -1
- package/dist/chat/chatLogic.esm.js +0 -116
- package/dist/chat/chatLogic.esm.js.map +0 -1
- package/dist/inbox/inboxLogic.cjs.js +0 -2
- package/dist/inbox/inboxLogic.cjs.js.map +0 -1
- package/dist/inbox/inboxLogic.esm.js +0 -37
- package/dist/inbox/inboxLogic.esm.js.map +0 -1
- package/dist/index.cjs.js +0 -2
- package/dist/index.cjs.js.map +0 -1
- package/dist/index.esm.js +0 -13
- package/dist/index.esm.js.map +0 -1
- package/dist/issuer/issuerLogic.cjs.js +0 -2
- package/dist/issuer/issuerLogic.cjs.js.map +0 -1
- package/dist/issuer/issuerLogic.esm.js +0 -30
- package/dist/issuer/issuerLogic.esm.js.map +0 -1
- package/dist/logic/CustomError.cjs.js +0 -2
- package/dist/logic/CustomError.cjs.js.map +0 -1
- package/dist/logic/CustomError.esm.js +0 -14
- package/dist/logic/CustomError.esm.js.map +0 -1
- package/dist/logic/solidLogic.cjs.js +0 -2
- package/dist/logic/solidLogic.cjs.js.map +0 -1
- package/dist/logic/solidLogic.esm.js +0 -47
- package/dist/logic/solidLogic.esm.js.map +0 -1
- package/dist/logic/solidLogicSingleton.cjs.js +0 -2
- package/dist/logic/solidLogicSingleton.cjs.js.map +0 -1
- package/dist/logic/solidLogicSingleton.esm.js +0 -19
- package/dist/logic/solidLogicSingleton.esm.js.map +0 -1
- package/dist/profile/profileAclDocuments.cjs.js +0 -3
- package/dist/profile/profileAclDocuments.cjs.js.map +0 -1
- package/dist/profile/profileAclDocuments.esm.js +0 -17
- package/dist/profile/profileAclDocuments.esm.js.map +0 -1
- package/dist/profile/profileDocuments.cjs.js +0 -3
- package/dist/profile/profileDocuments.cjs.js.map +0 -1
- package/dist/profile/profileDocuments.esm.js +0 -15
- package/dist/profile/profileDocuments.esm.js.map +0 -1
- package/dist/profile/profileLogic.cjs.js +0 -2
- package/dist/profile/profileLogic.cjs.js.map +0 -1
- package/dist/profile/profileLogic.esm.js +0 -184
- package/dist/profile/profileLogic.esm.js.map +0 -1
- package/dist/typeIndex/typeIndexAclDocuments.cjs.js +0 -3
- package/dist/typeIndex/typeIndexAclDocuments.cjs.js.map +0 -1
- package/dist/typeIndex/typeIndexAclDocuments.esm.js +0 -35
- package/dist/typeIndex/typeIndexAclDocuments.esm.js.map +0 -1
- package/dist/typeIndex/typeIndexDocuments.cjs.js +0 -4
- package/dist/typeIndex/typeIndexDocuments.cjs.js.map +0 -1
- package/dist/typeIndex/typeIndexDocuments.esm.js +0 -21
- package/dist/typeIndex/typeIndexDocuments.esm.js.map +0 -1
- package/dist/typeIndex/typeIndexLogic.cjs.js +0 -2
- package/dist/typeIndex/typeIndexLogic.cjs.js.map +0 -1
- package/dist/typeIndex/typeIndexLogic.esm.js +0 -185
- package/dist/typeIndex/typeIndexLogic.esm.js.map +0 -1
- package/dist/util/containerLogic.cjs.js +0 -2
- package/dist/util/containerLogic.cjs.js.map +0 -1
- package/dist/util/containerLogic.esm.js +0 -37
- package/dist/util/containerLogic.esm.js.map +0 -1
- package/dist/util/debug.cjs.js +0 -2
- package/dist/util/debug.cjs.js.map +0 -1
- package/dist/util/debug.esm.js +0 -11
- package/dist/util/debug.esm.js.map +0 -1
- package/dist/util/ns.cjs.js +0 -2
- package/dist/util/ns.cjs.js.map +0 -1
- package/dist/util/ns.esm.js +0 -8
- package/dist/util/ns.esm.js.map +0 -1
- package/dist/util/utilityLogic.cjs.js +0 -6
- package/dist/util/utilityLogic.cjs.js.map +0 -1
- package/dist/util/utilityLogic.esm.js +0 -149
- package/dist/util/utilityLogic.esm.js.map +0 -1
- package/dist/util/utils.cjs.js +0 -2
- package/dist/util/utils.cjs.js.map +0 -1
- package/dist/util/utils.esm.js +0 -22
- package/dist/util/utils.esm.js.map +0 -1
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { Session as e } from "@uvdsl/solid-oidc-client-browser";
|
|
2
|
-
import * as t from "@uvdsl/solid-oidc-client-browser/core";
|
|
3
|
-
//#region src/authSession/session.ts
|
|
4
|
-
var n = class {
|
|
5
|
-
constructor() {
|
|
6
|
-
this.map = /* @__PURE__ */ new Map();
|
|
7
|
-
}
|
|
8
|
-
shouldPreserveExistingRefreshToken(e, t) {
|
|
9
|
-
return e === "refresh_token" && (t == null || t === "") && this.map.has(e);
|
|
10
|
-
}
|
|
11
|
-
async init() {
|
|
12
|
-
return this;
|
|
13
|
-
}
|
|
14
|
-
async setItem(e, t) {
|
|
15
|
-
this.shouldPreserveExistingRefreshToken(e, t) || this.map.set(e, t);
|
|
16
|
-
}
|
|
17
|
-
async getItem(e) {
|
|
18
|
-
return this.map.has(e) ? this.map.get(e) : null;
|
|
19
|
-
}
|
|
20
|
-
async deleteItem(e) {
|
|
21
|
-
this.map.delete(e);
|
|
22
|
-
}
|
|
23
|
-
async clear() {
|
|
24
|
-
this.map.clear();
|
|
25
|
-
}
|
|
26
|
-
close() {}
|
|
27
|
-
}, r = class {
|
|
28
|
-
constructor() {
|
|
29
|
-
this.db = null, this.dbName = "soidc", this.storeName = "session", this.dbVersion = 1;
|
|
30
|
-
}
|
|
31
|
-
async shouldPreserveExistingRefreshToken(e, t) {
|
|
32
|
-
if (e !== "refresh_token" || !(t == null || t === "")) return !1;
|
|
33
|
-
let n = await this.getItem(e);
|
|
34
|
-
return n != null && n !== "";
|
|
35
|
-
}
|
|
36
|
-
async init() {
|
|
37
|
-
if (this.db) return this;
|
|
38
|
-
if (typeof indexedDB > "u") throw Error("IndexedDB is not available in this environment");
|
|
39
|
-
return await new Promise((e, t) => {
|
|
40
|
-
let n = indexedDB.open(this.dbName, this.dbVersion);
|
|
41
|
-
n.onerror = () => t(n.error), n.onsuccess = () => {
|
|
42
|
-
this.db = n.result, e();
|
|
43
|
-
}, n.onupgradeneeded = () => {
|
|
44
|
-
let e = n.result;
|
|
45
|
-
e.objectStoreNames.contains(this.storeName) || e.createObjectStore(this.storeName);
|
|
46
|
-
};
|
|
47
|
-
}), this;
|
|
48
|
-
}
|
|
49
|
-
async setItem(e, t) {
|
|
50
|
-
await this.init(), !await this.shouldPreserveExistingRefreshToken(e, t) && await this.withStore("readwrite", (n) => n.put(t, e));
|
|
51
|
-
}
|
|
52
|
-
async getItem(e) {
|
|
53
|
-
return await this.init(), this.withStore("readonly", (t) => t.get(e));
|
|
54
|
-
}
|
|
55
|
-
async deleteItem(e) {
|
|
56
|
-
await this.init(), await this.withStore("readwrite", (t) => t.delete(e));
|
|
57
|
-
}
|
|
58
|
-
async clear() {
|
|
59
|
-
await this.init(), await this.withStore("readwrite", (e) => e.clear());
|
|
60
|
-
}
|
|
61
|
-
close() {
|
|
62
|
-
this.db &&= (this.db.close(), null);
|
|
63
|
-
}
|
|
64
|
-
withStore(e, t) {
|
|
65
|
-
return new Promise((n, r) => {
|
|
66
|
-
if (!this.db) {
|
|
67
|
-
r(/* @__PURE__ */ Error("Session database not initialized"));
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
let i = this.db.transaction(this.storeName, e), a = t(i.objectStore(this.storeName)), o = null;
|
|
71
|
-
i.onerror = () => r(i.error ?? a.error), i.onabort = () => r(i.error ?? a.error ?? /* @__PURE__ */ Error("IndexedDB transaction aborted")), i.oncomplete = () => n(o), a.onerror = () => r(a.error), a.onsuccess = () => {
|
|
72
|
-
o = a.result ?? null;
|
|
73
|
-
};
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
function i() {
|
|
78
|
-
let e = t, n = e.SessionCore ?? e.default?.SessionCore ?? e.default;
|
|
79
|
-
return typeof n == "function" ? n : null;
|
|
80
|
-
}
|
|
81
|
-
var a = i();
|
|
82
|
-
function o() {
|
|
83
|
-
if (typeof window < "u" && (() => {
|
|
84
|
-
let e = window.location.hostname;
|
|
85
|
-
return e === "localhost" || e === "127.0.0.1" || e.endsWith(".localhost");
|
|
86
|
-
})()) return a ? new a(void 0, { database: new r() }) : new e();
|
|
87
|
-
try {
|
|
88
|
-
return new e();
|
|
89
|
-
} catch (t) {
|
|
90
|
-
console.warn("solid-logic: falling back to non-worker auth session:", t);
|
|
91
|
-
try {
|
|
92
|
-
return a ? new a(void 0, { database: new r() }) : new e();
|
|
93
|
-
} catch (t) {
|
|
94
|
-
return console.warn("solid-logic: IndexedDB unavailable, using in-memory session database:", t), a ? new a(void 0, { database: new n() }) : new e();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
var s = o();
|
|
99
|
-
//#endregion
|
|
100
|
-
export { r as IndexedDbSessionDatabase, n as MemorySessionDatabase, s as _session };
|
|
101
|
-
|
|
102
|
-
//# sourceMappingURL=session.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session.esm.js","names":[],"sources":["../../src/authSession/session.ts"],"sourcesContent":["/**\n * OIDC session factory.\n *\n * Everything needed to create and configure the underlying auth session:\n * - Session database backends (in-memory and IndexedDB)\n * - Session instantiation (WebSession or SessionCore, with local-dev\n * fallbacks for environments where the service worker can't load)\n * - Login compatibility shim that normalises legacy call-site signatures\n * and resolves the canonical issuer through /.well-known discovery\n *\n * The raw session instance (_session) is consumed by authSession.ts where\n * the legacy event layer and logout listener are attached.\n *\n * DO NOT import _session directly — always go through authSession.ts so\n * the event wiring is guaranteed to run.\n */\n\nimport {\n Session as WebSession,\n} from '@uvdsl/solid-oidc-client-browser'\nimport * as OidcCore from '@uvdsl/solid-oidc-client-browser/core'\nimport type { Session as OidcSession, SessionDatabase } from '@uvdsl/solid-oidc-client-browser/core'\n\n// ---------------------------------------------------------------------------\n// Session databases\n// ---------------------------------------------------------------------------\n\nexport class MemorySessionDatabase implements SessionDatabase {\n private readonly map = new Map<string, any>()\n\n private shouldPreserveExistingRefreshToken(id: string, value: any): boolean {\n return id === 'refresh_token' && (value == null || value === '') && this.map.has(id)\n }\n\n async init (): Promise<SessionDatabase> {\n return this\n }\n\n async setItem (id: string, value: any): Promise<void> {\n // Some Solid IdPs do not include refresh_token on refresh responses.\n // Keep the previous token instead of overwriting it with null/undefined.\n if (this.shouldPreserveExistingRefreshToken(id, value)) {\n return\n }\n this.map.set(id, value)\n }\n\n async getItem (id: string): Promise<any> {\n return this.map.has(id) ? this.map.get(id) : null\n }\n\n async deleteItem (id: string): Promise<void> {\n this.map.delete(id)\n }\n\n async clear (): Promise<void> {\n this.map.clear()\n }\n\n close (): void {\n // No-op for in-memory database\n }\n}\n\nexport class IndexedDbSessionDatabase implements SessionDatabase {\n private db: IDBDatabase | null = null\n private readonly dbName = 'soidc'\n private readonly storeName = 'session'\n private readonly dbVersion = 1\n\n private async shouldPreserveExistingRefreshToken(id: string, value: any): Promise<boolean> {\n if (id !== 'refresh_token' || !(value == null || value === '')) {\n return false\n }\n const existing = await this.getItem(id)\n return existing != null && existing !== ''\n }\n\n async init (): Promise<SessionDatabase> {\n if (this.db) return this\n if (typeof indexedDB === 'undefined') {\n throw new Error('IndexedDB is not available in this environment')\n }\n\n await new Promise<void>((resolve, reject) => {\n const request = indexedDB.open(this.dbName, this.dbVersion)\n\n request.onerror = () => reject(request.error)\n request.onsuccess = () => {\n this.db = request.result\n resolve()\n }\n request.onupgradeneeded = () => {\n const db = request.result\n if (!db.objectStoreNames.contains(this.storeName)) {\n db.createObjectStore(this.storeName)\n }\n }\n })\n\n return this\n }\n\n async setItem (id: string, value: any): Promise<void> {\n await this.init()\n // Some Solid IdPs do not include refresh_token on refresh responses.\n // Keep the previous token instead of overwriting it with null/undefined.\n if (await this.shouldPreserveExistingRefreshToken(id, value)) {\n return\n }\n await this.withStore('readwrite', store => store.put(value, id))\n }\n\n async getItem (id: string): Promise<any> {\n await this.init()\n return this.withStore('readonly', store => store.get(id))\n }\n\n async deleteItem (id: string): Promise<void> {\n await this.init()\n await this.withStore('readwrite', store => store.delete(id))\n }\n\n async clear (): Promise<void> {\n await this.init()\n await this.withStore('readwrite', store => store.clear())\n }\n\n close (): void {\n if (this.db) {\n this.db.close()\n this.db = null\n }\n }\n\n private withStore(mode: IDBTransactionMode, op: (store: IDBObjectStore) => IDBRequest<any>): Promise<any> {\n return new Promise<any>((resolve, reject) => {\n if (!this.db) {\n reject(new Error('Session database not initialized'))\n return\n }\n\n const tx = this.db.transaction(this.storeName, mode)\n const store = tx.objectStore(this.storeName)\n const request = op(store)\n let result: any = null\n\n tx.onerror = () => reject(tx.error ?? request.error)\n tx.onabort = () => reject(tx.error ?? request.error ?? new Error('IndexedDB transaction aborted'))\n tx.oncomplete = () => resolve(result)\n\n request.onerror = () => reject(request.error)\n request.onsuccess = () => {\n result = request.result ?? null\n }\n })\n }\n}\n\n// ---------------------------------------------------------------------------\n// Session instantiation\n// ---------------------------------------------------------------------------\n\nfunction getSessionCoreCtor (): (new (...args: any[]) => OidcSession) | null {\n const coreAny = OidcCore as any\n const candidate = coreAny.SessionCore ?? coreAny.default?.SessionCore ?? coreAny.default\n\n if (typeof candidate !== 'function') {\n return null\n }\n\n return candidate as new (...args: any[]) => OidcSession\n}\n\nconst SessionCoreCtor = getSessionCoreCtor()\n\nfunction createSession (): OidcSession {\n const shouldSkipWorkerInLocalDev = typeof window !== 'undefined' && (() => {\n const host = window.location.hostname\n // In local NSS setups (including subdomain mode like alice.localhost),\n // worker-based session storage can be brittle and lose state on reload.\n // Prefer SessionCore + IndexedDB for deterministic persistence.\n return host === 'localhost' || host === '127.0.0.1' || host.endsWith('.localhost')\n })()\n\n if (shouldSkipWorkerInLocalDev) {\n if (SessionCoreCtor) {\n return new SessionCoreCtor(undefined, { database: new IndexedDbSessionDatabase() })\n }\n return new WebSession()\n }\n\n try {\n return new WebSession()\n } catch (error) {\n // In some deployments, worker URL resolution can become file:// and fail cross-origin.\n // Fall back to SessionCore so auth still works without background refresh worker.\n // Use IndexedDB to keep refresh-token persistence across page reloads.\n console.warn('solid-logic: falling back to non-worker auth session:', error)\n try {\n if (SessionCoreCtor) {\n return new SessionCoreCtor(undefined, { database: new IndexedDbSessionDatabase() })\n }\n return new WebSession()\n } catch (dbError) {\n console.warn('solid-logic: IndexedDB unavailable, using in-memory session database:', dbError)\n if (SessionCoreCtor) {\n return new SessionCoreCtor(undefined, { database: new MemorySessionDatabase() })\n }\n return new WebSession()\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Singleton session\n// ---------------------------------------------------------------------------\n\nconst _session = createSession()\n\nexport { _session }\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("../util/debug.cjs.js"),t=require("./authUtil.cjs.js");let n=require("rdflib");var r=5e3;async function i(e){if(e===null)return;let t,n=new Promise(e=>{t=setTimeout(()=>e(void 0),r)});try{return await Promise.race([e,n])}finally{t!==void 0&&clearTimeout(t)}}var a=class{constructor(e){this.checkUserInFlight=null,this.sessionRestoreHookAttached=!1,this.fallbackWebId=null,this.session=e}get authSession(){return this.session}currentUser(){let e=t.appContext();if(e.viewingNoAuthPage)return(0,n.sym)(e.webId);let r=this.session,i=r?.info?.webId,a=r?.webId,o=i||a||this.fallbackWebId,s=r?.info?.isLoggedIn,c=r?.isActive,l=s===!0||c===!0||(s==null&&c==null?!!o:!1)||!!this.fallbackWebId;return this&&this.session&&o&&l?(0,n.sym)(o):t.offlineTestID()}async checkUser(t){let n=new URL(window.location.href).hash;n&&window.localStorage.setItem(`preLoginRedirectHash`,n);let r=this.session;!this.sessionRestoreHookAttached&&typeof r?.events?.on==`function`&&(r.events.on(`sessionRestore`,t=>{e.log(`Session restored to ${t}`),document.location.toString()!==t&&history.replaceState(null,``,t)}),this.sessionRestoreHookAttached=!0),this.checkUserInFlight||=this.resolveCurrentUser();let i=this.checkUserInFlight,a;try{a=await i}finally{this.checkUserInFlight===i&&(this.checkUserInFlight=null)}return Promise.resolve(t?t(a):a)}async resolveCurrentUser(){let n=this.session,r=new URL(window.location.href);if(r.hash=``,typeof n?.handleIncomingRedirect==`function`)await n.handleIncomingRedirect({restorePreviousSession:!0,url:r.href});else{let t=n?.isActive??!!n?.webId;if(typeof n?.restore==`function`){try{await i(n.restore())}catch(t){let n=t instanceof Error?t.message:String(t);if(!/no session to restore/i.test(n))throw t;e.log(`No previous session to restore`)}let r=n?.isActive??!!n?.webId;!t&&r&&n.events?.emit(`sessionRestore`,window.location.href)}if(typeof n?.handleRedirectFromLogin==`function`){let e=n?.isActive??!!n?.webId;await n.handleRedirectFromLogin();let t=n?.isActive??!!n?.webId;!e&&t&&n.events?.emit(`login`)}}let a=window.localStorage.getItem(`preLoginRedirectHash`);if(a){let e=new URL(window.location.href);e.hash!==a&&(history.pushState?history.pushState(null,document.title,a):location.hash=a,e.hash=a),window.localStorage.setItem(`preLoginRedirectHash`,``)}let o=t.offlineTestID();if(o)return o;let s=this.webIdFromSession(n?.info,n);return s||=await this.probeNssCookieBackedWebId(),s?this.fallbackWebId=s:this.fallbackWebId=null,s&&(o=this.saveUser(s)),o&&e.log(`(Logged in as ${o} by authentication)`),o}async probeNssCookieBackedWebId(){if(typeof window>`u`)return null;let{hostname:e,port:t,protocol:n}=window.location;if(!e.endsWith(`.localhost`))return null;let r=e.slice(0,-10);if(!r||r===`localhost`||r.includes(`.`))return null;try{return(await fetch(`/account/password/change`,{credentials:`include`,redirect:`manual`,cache:`no-store`})).status===403?`${`${n}//${e}${t?`:${t}`:``}`}/profile/card#me`:null}catch{return null}}saveUser(e,t){let r;if(e){r=typeof e==`string`?e:e.uri;let i=(0,n.namedNode)(r);return t&&(t.me=i),i}return null}webIdFromSession(e,t){let n=e?.webId||t?.webId;if(!n)return null;let r=e?.isLoggedIn,i=t?.isLoggedIn,a=t?.isActive;return r===!0||i===!0||a===!0?n:r===!1&&i===!1&&a===!1?null:n}};exports.SolidAuthnLogic=a;
|
|
2
|
-
//# sourceMappingURL=SolidAuthnLogic.cjs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SolidAuthnLogic.cjs.js","names":[],"sources":["../../src/authn/SolidAuthnLogic.ts"],"sourcesContent":["import { namedNode, NamedNode, sym } from 'rdflib'\nimport { appContext, offlineTestID } from './authUtil'\nimport * as debug from '../util/debug'\nimport type { SessionWithLegacyEvents } from '../authSession/authSession'\nimport type { AuthenticationContext, AuthnLogic } from '../types'\n\n// Some auth clients (uvdsl worker-backed session) only settle restore() on\n// a worker message; a missing/unreachable RefreshWorker asset makes it hang\n// forever. This caps the wait so the login UI can never spin indefinitely.\nconst SESSION_RESTORE_TIMEOUT_MS = 5000\n\n/**\n * Await a session restore promise, but give up after\n * SESSION_RESTORE_TIMEOUT_MS and resolve with undefined so callers can\n * treat a stalled restore as \"no previous session\".\n */\nasync function withRestoreTimeout<T> (promise: Promise<T> | null): Promise<T | undefined> {\n if (promise === null) return undefined\n let timer: ReturnType<typeof setTimeout> | undefined\n const timeout = new Promise<undefined>(resolve => {\n timer = setTimeout(() => resolve(undefined), SESSION_RESTORE_TIMEOUT_MS)\n })\n try {\n return await Promise.race([promise, timeout])\n } finally {\n if (timer !== undefined) clearTimeout(timer)\n }\n}\n\nexport class SolidAuthnLogic implements AuthnLogic {\n private session: SessionWithLegacyEvents\n private checkUserInFlight: Promise<NamedNode | null> | null = null\n private sessionRestoreHookAttached = false\n private fallbackWebId: string | null = null\n\n constructor(solidAuthSession: SessionWithLegacyEvents) {\n this.session = solidAuthSession\n }\n\n // we created authSession getter because we want to access it as authn.authSession externally\n get authSession(): SessionWithLegacyEvents { return this.session }\n\n currentUser(): NamedNode | null {\n const app = appContext()\n if (app.viewingNoAuthPage) {\n return sym(app.webId)\n }\n const sessionAny = this.session as any\n const infoWebId = sessionAny?.info?.webId\n const sessionWebId = sessionAny?.webId\n const webId = infoWebId || sessionWebId || this.fallbackWebId\n const infoLoggedIn = sessionAny?.info?.isLoggedIn\n const sessionActive = sessionAny?.isActive\n const isLoggedIn = infoLoggedIn === true || sessionActive === true ||\n ((infoLoggedIn == null && sessionActive == null) ? Boolean(webId) : false) ||\n Boolean(this.fallbackWebId)\n if (this && this.session && webId && isLoggedIn) {\n return sym(webId)\n }\n return offlineTestID() // null unless testing\n }\n\n /**\n * Retrieves currently logged in webId from either\n * defaultTestUser or SolidAuth\n * Also activates a session after login\n * @param [setUserCallback] Optional callback\n * @returns Resolves with webId uri, if no callback provided\n */\n async checkUser<T> (\n setUserCallback?: (me: NamedNode | null) => T\n ): Promise<NamedNode | T | null> {\n // Save hash for \"restorePreviousSession\"\n const preLoginRedirectHash = new URL(window.location.href).hash\n if (preLoginRedirectHash) {\n window.localStorage.setItem('preLoginRedirectHash', preLoginRedirectHash)\n }\n const sessionAny = this.session as any\n if (!this.sessionRestoreHookAttached && typeof sessionAny?.events?.on === 'function') {\n // Backward-compatible hook for auth clients exposing an EventEmitter-style API.\n sessionAny.events.on('sessionRestore', (url: string) => {\n debug.log(`Session restored to ${url}`)\n if (document.location.toString() !== url) history.replaceState(null, '', url)\n })\n this.sessionRestoreHookAttached = true\n }\n\n if (!this.checkUserInFlight) {\n this.checkUserInFlight = this.resolveCurrentUser()\n }\n\n const inFlight = this.checkUserInFlight\n let me: NamedNode | null\n try {\n me = await inFlight\n } finally {\n if (this.checkUserInFlight === inFlight) {\n this.checkUserInFlight = null\n }\n }\n\n return Promise.resolve(setUserCallback ? setUserCallback(me) : me)\n }\n\n private async resolveCurrentUser (): Promise<NamedNode | null> {\n const sessionAny = this.session as any\n\n /**\n * Handle a successful authentication redirect\n */\n const redirectUrl = new URL(window.location.href)\n redirectUrl.hash = ''\n if (typeof sessionAny?.handleIncomingRedirect === 'function') {\n await sessionAny.handleIncomingRedirect({\n restorePreviousSession: true,\n url: redirectUrl.href\n })\n } else {\n // uvdsl-style session (no handleIncomingRedirect): restore then handle redirect.\n //\n // The worker-backed session (WebWorkerSession) resolves restore() ONLY\n // when the SharedWorker posts a message back. If the worker asset can't\n // be fetched — local/dev servers that don't serve the RefreshWorker\n // chunk at the resolved URL, wrong MIME type, CSP, or a worker that\n // fails before `onconnect` — the promise never settles and the login\n // UI would spin forever. Race it against a timeout and treat a stall\n // as \"no previous session\" so the page can render the login button.\n const wasActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n if (typeof sessionAny?.restore === 'function') {\n try {\n await withRestoreTimeout(sessionAny.restore())\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n if (!/no session to restore/i.test(message)) {\n throw error\n }\n debug.log('No previous session to restore')\n }\n const isNowActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n if (!wasActive && isNowActive) {\n sessionAny.events?.emit('sessionRestore', window.location.href)\n }\n }\n if (typeof sessionAny?.handleRedirectFromLogin === 'function') {\n const wasActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n await sessionAny.handleRedirectFromLogin()\n const isNowActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n if (!wasActive && isNowActive) {\n sessionAny.events?.emit('login')\n }\n }\n }\n\n // Check to see if a hash was stored in local storage\n const postLoginRedirectHash = window.localStorage.getItem('preLoginRedirectHash')\n if (postLoginRedirectHash) {\n const curUrl = new URL(window.location.href)\n if (curUrl.hash !== postLoginRedirectHash) {\n if (history.pushState) {\n // debug.log('Setting window.location.has using pushState')\n history.pushState(null, document.title, postLoginRedirectHash)\n } else {\n // debug.warn('Setting window.location.has using location.hash')\n location.hash = postLoginRedirectHash\n }\n curUrl.hash = postLoginRedirectHash\n }\n // See https://stackoverflow.com/questions/3870057/how-can-i-update-window-location-hash-without-jumping-the-document\n // window.location.href = curUrl.toString()// @@ See https://developer.mozilla.org/en-US/docs/Web/API/Window/location\n window.localStorage.setItem('preLoginRedirectHash', '')\n }\n\n // Check to see if already logged in / have the WebID\n let me = offlineTestID()\n if (me) {\n return me\n }\n\n let webId = this.webIdFromSession(sessionAny?.info, sessionAny)\n if (!webId) {\n // NSS-specific fallback: recover WebID from NSS cookie session when client restore is empty.\n webId = await this.probeNssCookieBackedWebId()\n }\n\n if (webId) {\n this.fallbackWebId = webId\n } else {\n this.fallbackWebId = null\n }\n\n if (webId) {\n me = this.saveUser(webId)\n }\n\n if (me) {\n debug.log(`(Logged in as ${me} by authentication)`)\n }\n\n return me\n }\n\n private async probeNssCookieBackedWebId (): Promise<string | null> {\n if (typeof window === 'undefined') {\n return null\n }\n\n const { hostname, port, protocol } = window.location\n const localhostSuffix = '.localhost'\n // NSS local pods use subdomains like alice.localhost.\n if (!hostname.endsWith(localhostSuffix)) {\n return null\n }\n\n const podName = hostname.slice(0, -localhostSuffix.length)\n if (!podName || podName === 'localhost' || podName.includes('.')) {\n return null\n }\n\n try {\n // NSS returns 403 on this account page when the cookie session is valid.\n const probeResponse = await fetch('/account/password/change', {\n credentials: 'include',\n redirect: 'manual',\n cache: 'no-store'\n })\n if (probeResponse.status !== 403) {\n return null\n }\n const origin = `${protocol}//${hostname}${port ? `:${port}` : ''}`\n return `${origin}/profile/card#me`\n } catch (_error) {\n return null\n }\n }\n\n /**\n * Saves `webId` in `context.me`\n * @param webId\n * @param context\n *\n * @returns Returns the WebID, after setting it\n */\n saveUser (\n webId: NamedNode | string | null,\n context?: AuthenticationContext\n ): NamedNode | null {\n let webIdUri: string\n if (webId) {\n webIdUri = (typeof webId === 'string') ? webId : webId.uri\n const me = namedNode(webIdUri)\n if (context) {\n context.me = me\n }\n return me\n }\n return null\n }\n\n /**\n * @returns {Promise<string|null>} Resolves with WebID URI or null\n */\n webIdFromSession (\n sessionInfo?: { webId?: string, isLoggedIn?: boolean },\n sessionRoot?: { webId?: string, isLoggedIn?: boolean, isActive?: boolean }\n ): string | null {\n const webId = sessionInfo?.webId || sessionRoot?.webId\n if (!webId) {\n return null\n }\n const infoLoggedIn = sessionInfo?.isLoggedIn\n const rootLoggedIn = sessionRoot?.isLoggedIn\n const rootActive = sessionRoot?.isActive\n if (infoLoggedIn === true || rootLoggedIn === true || rootActive === true) {\n return webId\n }\n if (infoLoggedIn === false && rootLoggedIn === false && rootActive === false) {\n return null\n }\n return webId\n }\n\n}\n"],"mappings":"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"}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { log as e } from "../util/debug.esm.js";
|
|
2
|
-
import { appContext as t, offlineTestID as n } from "./authUtil.esm.js";
|
|
3
|
-
import { namedNode as r, sym as i } from "rdflib";
|
|
4
|
-
//#region src/authn/SolidAuthnLogic.ts
|
|
5
|
-
var a = 5e3;
|
|
6
|
-
async function o(e) {
|
|
7
|
-
if (e === null) return;
|
|
8
|
-
let t, n = new Promise((e) => {
|
|
9
|
-
t = setTimeout(() => e(void 0), a);
|
|
10
|
-
});
|
|
11
|
-
try {
|
|
12
|
-
return await Promise.race([e, n]);
|
|
13
|
-
} finally {
|
|
14
|
-
t !== void 0 && clearTimeout(t);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
var s = class {
|
|
18
|
-
constructor(e) {
|
|
19
|
-
this.checkUserInFlight = null, this.sessionRestoreHookAttached = !1, this.fallbackWebId = null, this.session = e;
|
|
20
|
-
}
|
|
21
|
-
get authSession() {
|
|
22
|
-
return this.session;
|
|
23
|
-
}
|
|
24
|
-
currentUser() {
|
|
25
|
-
let e = t();
|
|
26
|
-
if (e.viewingNoAuthPage) return i(e.webId);
|
|
27
|
-
let r = this.session, a = r?.info?.webId, o = r?.webId, s = a || o || this.fallbackWebId, c = r?.info?.isLoggedIn, l = r?.isActive, u = c === !0 || l === !0 || (c == null && l == null ? !!s : !1) || !!this.fallbackWebId;
|
|
28
|
-
return this && this.session && s && u ? i(s) : n();
|
|
29
|
-
}
|
|
30
|
-
async checkUser(t) {
|
|
31
|
-
let n = new URL(window.location.href).hash;
|
|
32
|
-
n && window.localStorage.setItem("preLoginRedirectHash", n);
|
|
33
|
-
let r = this.session;
|
|
34
|
-
!this.sessionRestoreHookAttached && typeof r?.events?.on == "function" && (r.events.on("sessionRestore", (t) => {
|
|
35
|
-
e(`Session restored to ${t}`), document.location.toString() !== t && history.replaceState(null, "", t);
|
|
36
|
-
}), this.sessionRestoreHookAttached = !0), this.checkUserInFlight ||= this.resolveCurrentUser();
|
|
37
|
-
let i = this.checkUserInFlight, a;
|
|
38
|
-
try {
|
|
39
|
-
a = await i;
|
|
40
|
-
} finally {
|
|
41
|
-
this.checkUserInFlight === i && (this.checkUserInFlight = null);
|
|
42
|
-
}
|
|
43
|
-
return Promise.resolve(t ? t(a) : a);
|
|
44
|
-
}
|
|
45
|
-
async resolveCurrentUser() {
|
|
46
|
-
let t = this.session, r = new URL(window.location.href);
|
|
47
|
-
if (r.hash = "", typeof t?.handleIncomingRedirect == "function") await t.handleIncomingRedirect({
|
|
48
|
-
restorePreviousSession: !0,
|
|
49
|
-
url: r.href
|
|
50
|
-
});
|
|
51
|
-
else {
|
|
52
|
-
let n = t?.isActive ?? !!t?.webId;
|
|
53
|
-
if (typeof t?.restore == "function") {
|
|
54
|
-
try {
|
|
55
|
-
await o(t.restore());
|
|
56
|
-
} catch (t) {
|
|
57
|
-
let n = t instanceof Error ? t.message : String(t);
|
|
58
|
-
if (!/no session to restore/i.test(n)) throw t;
|
|
59
|
-
e("No previous session to restore");
|
|
60
|
-
}
|
|
61
|
-
let r = t?.isActive ?? !!t?.webId;
|
|
62
|
-
!n && r && t.events?.emit("sessionRestore", window.location.href);
|
|
63
|
-
}
|
|
64
|
-
if (typeof t?.handleRedirectFromLogin == "function") {
|
|
65
|
-
let e = t?.isActive ?? !!t?.webId;
|
|
66
|
-
await t.handleRedirectFromLogin();
|
|
67
|
-
let n = t?.isActive ?? !!t?.webId;
|
|
68
|
-
!e && n && t.events?.emit("login");
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
let i = window.localStorage.getItem("preLoginRedirectHash");
|
|
72
|
-
if (i) {
|
|
73
|
-
let e = new URL(window.location.href);
|
|
74
|
-
e.hash !== i && (history.pushState ? history.pushState(null, document.title, i) : location.hash = i, e.hash = i), window.localStorage.setItem("preLoginRedirectHash", "");
|
|
75
|
-
}
|
|
76
|
-
let a = n();
|
|
77
|
-
if (a) return a;
|
|
78
|
-
let s = this.webIdFromSession(t?.info, t);
|
|
79
|
-
return s ||= await this.probeNssCookieBackedWebId(), s ? this.fallbackWebId = s : this.fallbackWebId = null, s && (a = this.saveUser(s)), a && e(`(Logged in as ${a} by authentication)`), a;
|
|
80
|
-
}
|
|
81
|
-
async probeNssCookieBackedWebId() {
|
|
82
|
-
if (typeof window > "u") return null;
|
|
83
|
-
let { hostname: e, port: t, protocol: n } = window.location;
|
|
84
|
-
if (!e.endsWith(".localhost")) return null;
|
|
85
|
-
let r = e.slice(0, -10);
|
|
86
|
-
if (!r || r === "localhost" || r.includes(".")) return null;
|
|
87
|
-
try {
|
|
88
|
-
return (await fetch("/account/password/change", {
|
|
89
|
-
credentials: "include",
|
|
90
|
-
redirect: "manual",
|
|
91
|
-
cache: "no-store"
|
|
92
|
-
})).status === 403 ? `${`${n}//${e}${t ? `:${t}` : ""}`}/profile/card#me` : null;
|
|
93
|
-
} catch {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
saveUser(e, t) {
|
|
98
|
-
let n;
|
|
99
|
-
if (e) {
|
|
100
|
-
n = typeof e == "string" ? e : e.uri;
|
|
101
|
-
let i = r(n);
|
|
102
|
-
return t && (t.me = i), i;
|
|
103
|
-
}
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
webIdFromSession(e, t) {
|
|
107
|
-
let n = e?.webId || t?.webId;
|
|
108
|
-
if (!n) return null;
|
|
109
|
-
let r = e?.isLoggedIn, i = t?.isLoggedIn, a = t?.isActive;
|
|
110
|
-
return r === !0 || i === !0 || a === !0 ? n : r === !1 && i === !1 && a === !1 ? null : n;
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
//#endregion
|
|
114
|
-
export { s as SolidAuthnLogic };
|
|
115
|
-
|
|
116
|
-
//# sourceMappingURL=SolidAuthnLogic.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SolidAuthnLogic.esm.js","names":[],"sources":["../../src/authn/SolidAuthnLogic.ts"],"sourcesContent":["import { namedNode, NamedNode, sym } from 'rdflib'\nimport { appContext, offlineTestID } from './authUtil'\nimport * as debug from '../util/debug'\nimport type { SessionWithLegacyEvents } from '../authSession/authSession'\nimport type { AuthenticationContext, AuthnLogic } from '../types'\n\n// Some auth clients (uvdsl worker-backed session) only settle restore() on\n// a worker message; a missing/unreachable RefreshWorker asset makes it hang\n// forever. This caps the wait so the login UI can never spin indefinitely.\nconst SESSION_RESTORE_TIMEOUT_MS = 5000\n\n/**\n * Await a session restore promise, but give up after\n * SESSION_RESTORE_TIMEOUT_MS and resolve with undefined so callers can\n * treat a stalled restore as \"no previous session\".\n */\nasync function withRestoreTimeout<T> (promise: Promise<T> | null): Promise<T | undefined> {\n if (promise === null) return undefined\n let timer: ReturnType<typeof setTimeout> | undefined\n const timeout = new Promise<undefined>(resolve => {\n timer = setTimeout(() => resolve(undefined), SESSION_RESTORE_TIMEOUT_MS)\n })\n try {\n return await Promise.race([promise, timeout])\n } finally {\n if (timer !== undefined) clearTimeout(timer)\n }\n}\n\nexport class SolidAuthnLogic implements AuthnLogic {\n private session: SessionWithLegacyEvents\n private checkUserInFlight: Promise<NamedNode | null> | null = null\n private sessionRestoreHookAttached = false\n private fallbackWebId: string | null = null\n\n constructor(solidAuthSession: SessionWithLegacyEvents) {\n this.session = solidAuthSession\n }\n\n // we created authSession getter because we want to access it as authn.authSession externally\n get authSession(): SessionWithLegacyEvents { return this.session }\n\n currentUser(): NamedNode | null {\n const app = appContext()\n if (app.viewingNoAuthPage) {\n return sym(app.webId)\n }\n const sessionAny = this.session as any\n const infoWebId = sessionAny?.info?.webId\n const sessionWebId = sessionAny?.webId\n const webId = infoWebId || sessionWebId || this.fallbackWebId\n const infoLoggedIn = sessionAny?.info?.isLoggedIn\n const sessionActive = sessionAny?.isActive\n const isLoggedIn = infoLoggedIn === true || sessionActive === true ||\n ((infoLoggedIn == null && sessionActive == null) ? Boolean(webId) : false) ||\n Boolean(this.fallbackWebId)\n if (this && this.session && webId && isLoggedIn) {\n return sym(webId)\n }\n return offlineTestID() // null unless testing\n }\n\n /**\n * Retrieves currently logged in webId from either\n * defaultTestUser or SolidAuth\n * Also activates a session after login\n * @param [setUserCallback] Optional callback\n * @returns Resolves with webId uri, if no callback provided\n */\n async checkUser<T> (\n setUserCallback?: (me: NamedNode | null) => T\n ): Promise<NamedNode | T | null> {\n // Save hash for \"restorePreviousSession\"\n const preLoginRedirectHash = new URL(window.location.href).hash\n if (preLoginRedirectHash) {\n window.localStorage.setItem('preLoginRedirectHash', preLoginRedirectHash)\n }\n const sessionAny = this.session as any\n if (!this.sessionRestoreHookAttached && typeof sessionAny?.events?.on === 'function') {\n // Backward-compatible hook for auth clients exposing an EventEmitter-style API.\n sessionAny.events.on('sessionRestore', (url: string) => {\n debug.log(`Session restored to ${url}`)\n if (document.location.toString() !== url) history.replaceState(null, '', url)\n })\n this.sessionRestoreHookAttached = true\n }\n\n if (!this.checkUserInFlight) {\n this.checkUserInFlight = this.resolveCurrentUser()\n }\n\n const inFlight = this.checkUserInFlight\n let me: NamedNode | null\n try {\n me = await inFlight\n } finally {\n if (this.checkUserInFlight === inFlight) {\n this.checkUserInFlight = null\n }\n }\n\n return Promise.resolve(setUserCallback ? setUserCallback(me) : me)\n }\n\n private async resolveCurrentUser (): Promise<NamedNode | null> {\n const sessionAny = this.session as any\n\n /**\n * Handle a successful authentication redirect\n */\n const redirectUrl = new URL(window.location.href)\n redirectUrl.hash = ''\n if (typeof sessionAny?.handleIncomingRedirect === 'function') {\n await sessionAny.handleIncomingRedirect({\n restorePreviousSession: true,\n url: redirectUrl.href\n })\n } else {\n // uvdsl-style session (no handleIncomingRedirect): restore then handle redirect.\n //\n // The worker-backed session (WebWorkerSession) resolves restore() ONLY\n // when the SharedWorker posts a message back. If the worker asset can't\n // be fetched — local/dev servers that don't serve the RefreshWorker\n // chunk at the resolved URL, wrong MIME type, CSP, or a worker that\n // fails before `onconnect` — the promise never settles and the login\n // UI would spin forever. Race it against a timeout and treat a stall\n // as \"no previous session\" so the page can render the login button.\n const wasActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n if (typeof sessionAny?.restore === 'function') {\n try {\n await withRestoreTimeout(sessionAny.restore())\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n if (!/no session to restore/i.test(message)) {\n throw error\n }\n debug.log('No previous session to restore')\n }\n const isNowActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n if (!wasActive && isNowActive) {\n sessionAny.events?.emit('sessionRestore', window.location.href)\n }\n }\n if (typeof sessionAny?.handleRedirectFromLogin === 'function') {\n const wasActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n await sessionAny.handleRedirectFromLogin()\n const isNowActive = sessionAny?.isActive ?? Boolean(sessionAny?.webId)\n if (!wasActive && isNowActive) {\n sessionAny.events?.emit('login')\n }\n }\n }\n\n // Check to see if a hash was stored in local storage\n const postLoginRedirectHash = window.localStorage.getItem('preLoginRedirectHash')\n if (postLoginRedirectHash) {\n const curUrl = new URL(window.location.href)\n if (curUrl.hash !== postLoginRedirectHash) {\n if (history.pushState) {\n // debug.log('Setting window.location.has using pushState')\n history.pushState(null, document.title, postLoginRedirectHash)\n } else {\n // debug.warn('Setting window.location.has using location.hash')\n location.hash = postLoginRedirectHash\n }\n curUrl.hash = postLoginRedirectHash\n }\n // See https://stackoverflow.com/questions/3870057/how-can-i-update-window-location-hash-without-jumping-the-document\n // window.location.href = curUrl.toString()// @@ See https://developer.mozilla.org/en-US/docs/Web/API/Window/location\n window.localStorage.setItem('preLoginRedirectHash', '')\n }\n\n // Check to see if already logged in / have the WebID\n let me = offlineTestID()\n if (me) {\n return me\n }\n\n let webId = this.webIdFromSession(sessionAny?.info, sessionAny)\n if (!webId) {\n // NSS-specific fallback: recover WebID from NSS cookie session when client restore is empty.\n webId = await this.probeNssCookieBackedWebId()\n }\n\n if (webId) {\n this.fallbackWebId = webId\n } else {\n this.fallbackWebId = null\n }\n\n if (webId) {\n me = this.saveUser(webId)\n }\n\n if (me) {\n debug.log(`(Logged in as ${me} by authentication)`)\n }\n\n return me\n }\n\n private async probeNssCookieBackedWebId (): Promise<string | null> {\n if (typeof window === 'undefined') {\n return null\n }\n\n const { hostname, port, protocol } = window.location\n const localhostSuffix = '.localhost'\n // NSS local pods use subdomains like alice.localhost.\n if (!hostname.endsWith(localhostSuffix)) {\n return null\n }\n\n const podName = hostname.slice(0, -localhostSuffix.length)\n if (!podName || podName === 'localhost' || podName.includes('.')) {\n return null\n }\n\n try {\n // NSS returns 403 on this account page when the cookie session is valid.\n const probeResponse = await fetch('/account/password/change', {\n credentials: 'include',\n redirect: 'manual',\n cache: 'no-store'\n })\n if (probeResponse.status !== 403) {\n return null\n }\n const origin = `${protocol}//${hostname}${port ? `:${port}` : ''}`\n return `${origin}/profile/card#me`\n } catch (_error) {\n return null\n }\n }\n\n /**\n * Saves `webId` in `context.me`\n * @param webId\n * @param context\n *\n * @returns Returns the WebID, after setting it\n */\n saveUser (\n webId: NamedNode | string | null,\n context?: AuthenticationContext\n ): NamedNode | null {\n let webIdUri: string\n if (webId) {\n webIdUri = (typeof webId === 'string') ? webId : webId.uri\n const me = namedNode(webIdUri)\n if (context) {\n context.me = me\n }\n return me\n }\n return null\n }\n\n /**\n * @returns {Promise<string|null>} Resolves with WebID URI or null\n */\n webIdFromSession (\n sessionInfo?: { webId?: string, isLoggedIn?: boolean },\n sessionRoot?: { webId?: string, isLoggedIn?: boolean, isActive?: boolean }\n ): string | null {\n const webId = sessionInfo?.webId || sessionRoot?.webId\n if (!webId) {\n return null\n }\n const infoLoggedIn = sessionInfo?.isLoggedIn\n const rootLoggedIn = sessionRoot?.isLoggedIn\n const rootActive = sessionRoot?.isActive\n if (infoLoggedIn === true || rootLoggedIn === true || rootActive === true) {\n return webId\n }\n if (infoLoggedIn === false && rootLoggedIn === false && rootActive === false) {\n return null\n }\n return webId\n }\n\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("../util/debug.cjs.js");let t=require("rdflib");var n=()=>{let{SolidAppContext:e}=window;if(e||={},e.viewingNoAuthPage=!1,e.noAuth&&window.document&&window.document.location.href.startsWith(e.noAuth)){e.viewingNoAuthPage=!0;let t=new URLSearchParams(window.document.location.search);if(t){let n=e.viewedPage=t.get(`uri`)||null;if(n&&(n=decodeURI(n),!n.startsWith(e.noAuth))){let t=n.split(/\//);e.idp=t[0]+`//`+t[2],e.viewingNoAuthPage=!1}}}return e};function r(){let{$SolidTestEnvironment:n}=window;if(n!==void 0&&n.username)return e.log(`Assuming the user is `+n.username),(0,t.sym)(n.username);if(typeof document<`u`&&document.location&&(``+document.location).slice(0,16)===`http://localhost`){let n=document.getElementById(`appTarget`);if(!n)return null;let r=n.getAttribute(`testID`);return r?(e.log(`Assuming user is `+r),(0,t.sym)(r)):null}return null}exports.appContext=n,exports.offlineTestID=r;
|
|
2
|
-
//# sourceMappingURL=authUtil.cjs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authUtil.cjs.js","names":[],"sources":["../../src/authn/authUtil.ts"],"sourcesContent":["import { NamedNode, sym } from 'rdflib'\nimport * as debug from '../util/debug'\n\n/**\n * find a user or app's context as set in window.SolidAppContext\n * this is a const, not a function, because we have problems to jest mock it otherwise\n * see: https://github.com/facebook/jest/issues/936#issuecomment-545080082 for more\n * @return {any} - an appContext object\n */\nexport const appContext = ():any => {\n let { SolidAppContext }: any = window\n SolidAppContext ||= {}\n SolidAppContext.viewingNoAuthPage = false\n if (SolidAppContext.noAuth && window.document) {\n const currentPage = window.document.location.href\n if (currentPage.startsWith(SolidAppContext.noAuth)) {\n SolidAppContext.viewingNoAuthPage = true\n const params = new URLSearchParams(window.document.location.search)\n if (params) {\n let viewedPage = SolidAppContext.viewedPage = params.get('uri') || null\n if (viewedPage) {\n viewedPage = decodeURI(viewedPage)\n if (!viewedPage.startsWith(SolidAppContext.noAuth)) {\n const ary = viewedPage.split(/\\//)\n SolidAppContext.idp = ary[0] + '//' + ary[2]\n SolidAppContext.viewingNoAuthPage = false\n }\n }\n }\n }\n }\n return SolidAppContext\n}\n\n/**\n * Returns `sym($SolidTestEnvironment.username)` if\n * `$SolidTestEnvironment.username` is defined as a global\n * or \n * returns testID defined in the HTML page\n * @returns {NamedNode|null}\n */\nexport function offlineTestID (): NamedNode | null {\n const { $SolidTestEnvironment }: any = window\n if (\n typeof $SolidTestEnvironment !== 'undefined' &&\n $SolidTestEnvironment.username\n ) {\n // Test setup\n debug.log('Assuming the user is ' + $SolidTestEnvironment.username)\n return sym($SolidTestEnvironment.username)\n }\n // hack that makes SolidOS work in offline mode by adding the webId directly in html\n // example usage: https://github.com/solidos/mashlib/blob/29b8b53c46bf02e0e219f0bacd51b0e9951001dd/test/contact/local.html#L37\n if (\n typeof document !== 'undefined' &&\n document.location &&\n ('' + document.location).slice(0, 16) === 'http://localhost'\n ) {\n const div = document.getElementById('appTarget')\n if (!div) return null\n const id = div.getAttribute('testID')\n if (!id) return null\n debug.log('Assuming user is ' + id)\n return sym(id)\n }\n return null\n}\n"],"mappings":"gEASA,IAAa,MAAuB,CAChC,GAAI,CAAE,mBAAyB,OAG/B,GAFA,IAAoB,CAAC,EACrB,EAAgB,kBAAoB,GAChC,EAAgB,QAAU,OAAO,UACb,OAAO,SAAS,SAAS,KAC7B,WAAW,EAAgB,MAAM,EAAG,CACpD,EAAgB,kBAAoB,GACpC,IAAM,EAAS,IAAI,gBAAgB,OAAO,SAAS,SAAS,MAAM,EAClE,GAAI,EAAQ,CACR,IAAI,EAAa,EAAgB,WAAa,EAAO,IAAI,KAAK,GAAK,KACnE,GAAI,IACJ,EAAa,UAAU,CAAU,EAC7B,CAAC,EAAW,WAAW,EAAgB,MAAM,GAAG,CAChD,IAAM,EAAM,EAAW,MAAM,IAAI,EACjC,EAAgB,IAAM,EAAI,GAAK,KAAO,EAAI,GAC1C,EAAgB,kBAAoB,EACxC,CAEJ,CACA,CAEJ,OAAO,CACX,EASA,SAAgB,GAAmC,CAC/C,GAAM,CAAE,yBAA+B,OACvC,GACS,IAA0B,QACjC,EAAsB,SAItB,OADA,EAAA,IAAU,wBAA0B,EAAsB,QAAQ,GAClE,EAAA,EAAA,IAAA,CAAW,EAAsB,QAAQ,EAI3C,GACE,OAAO,SAAa,KACpB,SAAS,WACR,GAAK,SAAS,SAAA,CAAU,MAAM,EAAG,EAAE,IAAM,mBAC1C,CACA,IAAM,EAAM,SAAS,eAAe,WAAW,EAC/C,GAAI,CAAC,EAAK,OAAO,KACjB,IAAM,EAAK,EAAI,aAAa,QAAQ,EAGpC,OAFK,GACL,EAAA,IAAU,oBAAsB,CAAE,GAClC,EAAA,EAAA,IAAA,CAAW,CAAE,GAFG,IAGlB,CACA,OAAO,IACX"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { log as e } from "../util/debug.esm.js";
|
|
2
|
-
import { sym as t } from "rdflib";
|
|
3
|
-
//#region src/authn/authUtil.ts
|
|
4
|
-
var n = () => {
|
|
5
|
-
let { SolidAppContext: e } = window;
|
|
6
|
-
if (e ||= {}, e.viewingNoAuthPage = !1, e.noAuth && window.document && window.document.location.href.startsWith(e.noAuth)) {
|
|
7
|
-
e.viewingNoAuthPage = !0;
|
|
8
|
-
let t = new URLSearchParams(window.document.location.search);
|
|
9
|
-
if (t) {
|
|
10
|
-
let n = e.viewedPage = t.get("uri") || null;
|
|
11
|
-
if (n && (n = decodeURI(n), !n.startsWith(e.noAuth))) {
|
|
12
|
-
let t = n.split(/\//);
|
|
13
|
-
e.idp = t[0] + "//" + t[2], e.viewingNoAuthPage = !1;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return e;
|
|
18
|
-
};
|
|
19
|
-
function r() {
|
|
20
|
-
let { $SolidTestEnvironment: n } = window;
|
|
21
|
-
if (n !== void 0 && n.username) return e("Assuming the user is " + n.username), t(n.username);
|
|
22
|
-
if (typeof document < "u" && document.location && ("" + document.location).slice(0, 16) === "http://localhost") {
|
|
23
|
-
let n = document.getElementById("appTarget");
|
|
24
|
-
if (!n) return null;
|
|
25
|
-
let r = n.getAttribute("testID");
|
|
26
|
-
return r ? (e("Assuming user is " + r), t(r)) : null;
|
|
27
|
-
}
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
//#endregion
|
|
31
|
-
export { n as appContext, r as offlineTestID };
|
|
32
|
-
|
|
33
|
-
//# sourceMappingURL=authUtil.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authUtil.esm.js","names":[],"sources":["../../src/authn/authUtil.ts"],"sourcesContent":["import { NamedNode, sym } from 'rdflib'\nimport * as debug from '../util/debug'\n\n/**\n * find a user or app's context as set in window.SolidAppContext\n * this is a const, not a function, because we have problems to jest mock it otherwise\n * see: https://github.com/facebook/jest/issues/936#issuecomment-545080082 for more\n * @return {any} - an appContext object\n */\nexport const appContext = ():any => {\n let { SolidAppContext }: any = window\n SolidAppContext ||= {}\n SolidAppContext.viewingNoAuthPage = false\n if (SolidAppContext.noAuth && window.document) {\n const currentPage = window.document.location.href\n if (currentPage.startsWith(SolidAppContext.noAuth)) {\n SolidAppContext.viewingNoAuthPage = true\n const params = new URLSearchParams(window.document.location.search)\n if (params) {\n let viewedPage = SolidAppContext.viewedPage = params.get('uri') || null\n if (viewedPage) {\n viewedPage = decodeURI(viewedPage)\n if (!viewedPage.startsWith(SolidAppContext.noAuth)) {\n const ary = viewedPage.split(/\\//)\n SolidAppContext.idp = ary[0] + '//' + ary[2]\n SolidAppContext.viewingNoAuthPage = false\n }\n }\n }\n }\n }\n return SolidAppContext\n}\n\n/**\n * Returns `sym($SolidTestEnvironment.username)` if\n * `$SolidTestEnvironment.username` is defined as a global\n * or \n * returns testID defined in the HTML page\n * @returns {NamedNode|null}\n */\nexport function offlineTestID (): NamedNode | null {\n const { $SolidTestEnvironment }: any = window\n if (\n typeof $SolidTestEnvironment !== 'undefined' &&\n $SolidTestEnvironment.username\n ) {\n // Test setup\n debug.log('Assuming the user is ' + $SolidTestEnvironment.username)\n return sym($SolidTestEnvironment.username)\n }\n // hack that makes SolidOS work in offline mode by adding the webId directly in html\n // example usage: https://github.com/solidos/mashlib/blob/29b8b53c46bf02e0e219f0bacd51b0e9951001dd/test/contact/local.html#L37\n if (\n typeof document !== 'undefined' &&\n document.location &&\n ('' + document.location).slice(0, 16) === 'http://localhost'\n ) {\n const div = document.getElementById('appTarget')\n if (!div) return null\n const id = div.getAttribute('testID')\n if (!id) return null\n debug.log('Assuming user is ' + id)\n return sym(id)\n }\n return null\n}\n"],"mappings":";;;AASA,IAAa,UAAuB;CAChC,IAAI,EAAE,uBAAyB;CAG/B,IAFA,MAAoB,CAAC,GACrB,EAAgB,oBAAoB,IAChC,EAAgB,UAAU,OAAO,YACb,OAAO,SAAS,SAAS,KAC7B,WAAW,EAAgB,MAAM,GAAG;EACpD,EAAgB,oBAAoB;EACpC,IAAM,IAAS,IAAI,gBAAgB,OAAO,SAAS,SAAS,MAAM;EAClE,IAAI,GAAQ;GACR,IAAI,IAAa,EAAgB,aAAa,EAAO,IAAI,KAAK,KAAK;GACnE,IAAI,MACJ,IAAa,UAAU,CAAU,GAC7B,CAAC,EAAW,WAAW,EAAgB,MAAM,IAAG;IAChD,IAAM,IAAM,EAAW,MAAM,IAAI;IAEjC,AADA,EAAgB,MAAM,EAAI,KAAK,OAAO,EAAI,IAC1C,EAAgB,oBAAoB;GACxC;EAEJ;CACA;CAEJ,OAAO;AACX;AASA,SAAgB,IAAmC;CAC/C,IAAM,EAAE,6BAA+B;CACvC,IACS,MAA0B,UACjC,EAAsB,UAItB,OADA,EAAU,0BAA0B,EAAsB,QAAQ,GAC3D,EAAI,EAAsB,QAAQ;CAI3C,IACE,OAAO,WAAa,OACpB,SAAS,aACR,KAAK,SAAS,SAAA,CAAU,MAAM,GAAG,EAAE,MAAM,oBAC1C;EACA,IAAM,IAAM,SAAS,eAAe,WAAW;EAC/C,IAAI,CAAC,GAAK,OAAO;EACjB,IAAM,IAAK,EAAI,aAAa,QAAQ;EAGpC,OAFK,KACL,EAAU,sBAAsB,CAAE,GAC3B,EAAI,CAAE,KAFG;CAGlB;CACA,OAAO;AACX"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
async function e(e={}){if(typeof window>`u`)return!1;let t=e.issuer||``,n=e.postLogoutRedirectPath||`/`;try{if(t){let e=new URL(t);e.pathname=`/.well-known/openid-configuration`;let n=await fetch(e.toString(),{credentials:`include`});if(n.status===200){let e=await n.json();e&&e.end_session_endpoint&&await fetch(e.end_session_endpoint,{credentials:`include`})}}}catch{}try{let e=await fetch(`/.well-known/solid/logout`,{credentials:`include`});if(e.ok||e.redirected)return window.location.assign(n),!0}catch{}return!1}exports.performServerSideLogout=e;
|
|
2
|
-
//# sourceMappingURL=serverLogout.cjs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"serverLogout.cjs.js","names":[],"sources":["../../src/authn/serverLogout.ts"],"sourcesContent":["export type ServerLogoutOptions = {\n issuer?: string\n postLogoutRedirectPath?: string\n}\n\nexport async function performServerSideLogout (options: ServerLogoutOptions = {}): Promise<boolean> {\n if (typeof window === 'undefined') {\n return false\n }\n const issuer = options.issuer || ''\n const postLogoutRedirectPath = options.postLogoutRedirectPath || '/'\n\n // Provider-specific logout endpoint discovery (OIDC end_session_endpoint).\n try {\n if (issuer) {\n const wellKnownUri = new URL(issuer)\n wellKnownUri.pathname = '/.well-known/openid-configuration'\n const wellKnownResult = await fetch(wellKnownUri.toString(), { credentials: 'include' })\n\n if (wellKnownResult.status === 200) {\n const openidConfiguration = await wellKnownResult.json()\n if (openidConfiguration && openidConfiguration.end_session_endpoint) {\n await fetch(openidConfiguration.end_session_endpoint, { credentials: 'include' })\n }\n }\n }\n } catch (_err) {\n // Continue with local logout even if provider logout is unavailable.\n }\n\n // NSS well-known logout endpoint clears cookie-backed server sessions.\n try {\n const logoutResponse = await fetch('/.well-known/solid/logout', { credentials: 'include' })\n if (logoutResponse.ok || logoutResponse.redirected) {\n window.location.assign(postLogoutRedirectPath)\n return true\n }\n } catch (_err) {\n // Not all deployments expose this endpoint.\n }\n\n return false\n}"],"mappings":"AAKA,eAAsB,EAAyB,EAA+B,CAAC,EAAqB,CAClG,GAAI,OAAO,OAAW,IACpB,MAAO,GAET,IAAM,EAAS,EAAQ,QAAU,GAC3B,EAAyB,EAAQ,wBAA0B,IAGjE,GAAI,CACF,GAAI,EAAQ,CACV,IAAM,EAAe,IAAI,IAAI,CAAM,EACnC,EAAa,SAAW,oCACxB,IAAM,EAAkB,MAAM,MAAM,EAAa,SAAS,EAAG,CAAE,YAAa,SAAU,CAAC,EAEvF,GAAI,EAAgB,SAAW,IAAK,CAClC,IAAM,EAAsB,MAAM,EAAgB,KAAK,EACnD,GAAuB,EAAoB,sBAC7C,MAAM,MAAM,EAAoB,qBAAsB,CAAE,YAAa,SAAU,CAAC,CAEpF,CACF,CACF,MAAe,CAEf,CAGA,GAAI,CACF,IAAM,EAAiB,MAAM,MAAM,4BAA6B,CAAE,YAAa,SAAU,CAAC,EAC1F,GAAI,EAAe,IAAM,EAAe,WAEtC,OADA,OAAO,SAAS,OAAO,CAAsB,EACtC,EAEX,MAAe,CAEf,CAEA,MAAO,EACT"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
//#region src/authn/serverLogout.ts
|
|
2
|
-
async function e(e = {}) {
|
|
3
|
-
if (typeof window > "u") return !1;
|
|
4
|
-
let t = e.issuer || "", n = e.postLogoutRedirectPath || "/";
|
|
5
|
-
try {
|
|
6
|
-
if (t) {
|
|
7
|
-
let e = new URL(t);
|
|
8
|
-
e.pathname = "/.well-known/openid-configuration";
|
|
9
|
-
let n = await fetch(e.toString(), { credentials: "include" });
|
|
10
|
-
if (n.status === 200) {
|
|
11
|
-
let e = await n.json();
|
|
12
|
-
e && e.end_session_endpoint && await fetch(e.end_session_endpoint, { credentials: "include" });
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
} catch {}
|
|
16
|
-
try {
|
|
17
|
-
let e = await fetch("/.well-known/solid/logout", { credentials: "include" });
|
|
18
|
-
if (e.ok || e.redirected) return window.location.assign(n), !0;
|
|
19
|
-
} catch {}
|
|
20
|
-
return !1;
|
|
21
|
-
}
|
|
22
|
-
//#endregion
|
|
23
|
-
export { e as performServerSideLogout };
|
|
24
|
-
|
|
25
|
-
//# sourceMappingURL=serverLogout.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"serverLogout.esm.js","names":[],"sources":["../../src/authn/serverLogout.ts"],"sourcesContent":["export type ServerLogoutOptions = {\n issuer?: string\n postLogoutRedirectPath?: string\n}\n\nexport async function performServerSideLogout (options: ServerLogoutOptions = {}): Promise<boolean> {\n if (typeof window === 'undefined') {\n return false\n }\n const issuer = options.issuer || ''\n const postLogoutRedirectPath = options.postLogoutRedirectPath || '/'\n\n // Provider-specific logout endpoint discovery (OIDC end_session_endpoint).\n try {\n if (issuer) {\n const wellKnownUri = new URL(issuer)\n wellKnownUri.pathname = '/.well-known/openid-configuration'\n const wellKnownResult = await fetch(wellKnownUri.toString(), { credentials: 'include' })\n\n if (wellKnownResult.status === 200) {\n const openidConfiguration = await wellKnownResult.json()\n if (openidConfiguration && openidConfiguration.end_session_endpoint) {\n await fetch(openidConfiguration.end_session_endpoint, { credentials: 'include' })\n }\n }\n }\n } catch (_err) {\n // Continue with local logout even if provider logout is unavailable.\n }\n\n // NSS well-known logout endpoint clears cookie-backed server sessions.\n try {\n const logoutResponse = await fetch('/.well-known/solid/logout', { credentials: 'include' })\n if (logoutResponse.ok || logoutResponse.redirected) {\n window.location.assign(postLogoutRedirectPath)\n return true\n }\n } catch (_err) {\n // Not all deployments expose this endpoint.\n }\n\n return false\n}"],"mappings":";AAKA,eAAsB,EAAyB,IAA+B,CAAC,GAAqB;CAClG,IAAI,OAAO,SAAW,KACpB,OAAO;CAET,IAAM,IAAS,EAAQ,UAAU,IAC3B,IAAyB,EAAQ,0BAA0B;CAGjE,IAAI;EACF,IAAI,GAAQ;GACV,IAAM,IAAe,IAAI,IAAI,CAAM;GACnC,EAAa,WAAW;GACxB,IAAM,IAAkB,MAAM,MAAM,EAAa,SAAS,GAAG,EAAE,aAAa,UAAU,CAAC;GAEvF,IAAI,EAAgB,WAAW,KAAK;IAClC,IAAM,IAAsB,MAAM,EAAgB,KAAK;IACvD,AAAI,KAAuB,EAAoB,wBAC7C,MAAM,MAAM,EAAoB,sBAAsB,EAAE,aAAa,UAAU,CAAC;GAEpF;EACF;CACF,QAAe,CAEf;CAGA,IAAI;EACF,IAAM,IAAiB,MAAM,MAAM,6BAA6B,EAAE,aAAa,UAAU,CAAC;EAC1F,IAAI,EAAe,MAAM,EAAe,YAEtC,OADA,OAAO,SAAS,OAAO,CAAsB,GACtC;CAEX,QAAe,CAEf;CAEA,OAAO;AACT"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
const e=require("../util/ns.cjs.js"),t=require("../util/utils.cjs.js");let n=require("rdflib");var r=`index.ttl#this`;function i(i,a){let o=e.ns;async function s(e,t,r){await i.fetcher.load(e);let a=i.any(e,new n.NamedNode(`http://www.iana.org/assignments/link-relations/acl`));if(!a)throw Error(`Chat ACL doc not found!`);let o=`
|
|
2
|
-
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
|
|
3
|
-
<#owner>
|
|
4
|
-
a acl:Authorization;
|
|
5
|
-
acl:agent <${t.value}>;
|
|
6
|
-
acl:accessTo <.>;
|
|
7
|
-
acl:default <.>;
|
|
8
|
-
acl:mode
|
|
9
|
-
acl:Read, acl:Write, acl:Control.
|
|
10
|
-
<#invitee>
|
|
11
|
-
a acl:Authorization;
|
|
12
|
-
acl:agent <${r.value}>;
|
|
13
|
-
acl:accessTo <.>;
|
|
14
|
-
acl:default <.>;
|
|
15
|
-
acl:mode
|
|
16
|
-
acl:Read, acl:Append.
|
|
17
|
-
`;await i.fetcher.webOperation(`PUT`,a.value,{data:o,contentType:`text/turtle`})}async function c(e,r){let a=i.any(r,o.solid(`privateTypeIndex`));if(!a)throw Error(`Private type index not found!`);await i.fetcher.load(a);let s=t.newThing(a),c=[(0,n.st)(s,o.rdf(`type`),o.solid(`TypeRegistration`),a.doc()),(0,n.st)(s,o.solid(`forClass`),o.meeting(`LongChat`),a.doc()),(0,n.st)(s,o.solid(`instance`),e,a.doc())];await new Promise((e,t)=>{i.updater.update([],c,function(n,r,i){r?e(null):t(Error(i))})})}async function l(e){let r=await a.loadMe(),o=t.determineChatContainer(e,await a.getPodRoot(r)),s=!0;try{await i.fetcher.load(new n.NamedNode(o.value+`index.ttl#this`))}catch{s=!1}return{me:r,chatContainer:o,exists:s}}async function u(e,t){return(await d({me:t,newBase:e.value})).newInstance}function d(e){let t=i,a=t.updater;if(e.me&&!e.me.uri)throw Error(`chat mintNew: Invalid userid `+e.me);let s=e.newInstance=e.newInstance||t.sym(e.newBase+r),c=s.doc();return t.add(s,o.rdf(`type`),o.meeting(`LongChat`),c),t.add(s,o.dc(`title`),`Chat channel`,c),t.add(s,o.dc(`created`),(0,n.term)(new Date(Date.now())),c),e.me&&t.add(s,o.dc(`author`),e.me,c),new Promise(function(n,r){a?.put(c,t.statementsMatching(void 0,void 0,void 0,c),`text/turtle`,function(t,i,a){i?n({...e,newInstance:s}):r(Error(`FAILED to save new chat channel at: `+t+` : `+a))})})}async function f(e,t=!0){let{me:i,chatContainer:a,exists:o}=await l(e);if(o)return new n.NamedNode(a.value+r);if(t){let t=await u(a,i);return await p(e,t),await s(a,i,e),await c(t,i),t}return null}async function p(e,t){await i.fetcher.load(e.doc());let n=i.any(e,o.ldp(`inbox`),void 0,e.doc());if(!n)throw Error(`Invitee inbox not found! ${e.value}`);let r=`
|
|
18
|
-
<> a <http://www.w3.org/ns/pim/meeting#LongChatInvite> ;
|
|
19
|
-
${o.rdf(`seeAlso`)} <${t.value}> .
|
|
20
|
-
`,a=await i.fetcher?.webOperation(`POST`,n.value,{data:r,contentType:`text/turtle`});if(!a?.headers.get(`location`))throw Error(`Invite sending returned a ${a?.status}`)}return{setAcl:s,addToPrivateTypeIndex:c,findChat:l,createChatThing:u,getChat:f,sendInvite:p,mintNew:d}}exports.createChatLogic=i;
|
|
21
|
-
//# sourceMappingURL=chatLogic.cjs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chatLogic.cjs.js","names":[],"sources":["../../src/chat/chatLogic.ts"],"sourcesContent":["import { NamedNode, Node, st, term } from 'rdflib'\nimport { ChatLogic, CreatedPaneOptions, NewPaneOptions, Chat } from '../types'\nimport { ns as namespace } from '../util/ns'\nimport { determineChatContainer, newThing } from '../util/utils'\n\nconst CHAT_LOCATION_IN_CONTAINER = 'index.ttl#this'\n\nexport function createChatLogic(store, profileLogic): ChatLogic {\n const ns = namespace\n\n async function setAcl(\n chatContainer: NamedNode,\n me: NamedNode,\n invitee: NamedNode\n ): Promise<void> {\n // Some servers don't present a Link http response header\n // if the container doesn't exist yet, so refetch the container\n // now that it has been created:\n await store.fetcher.load(chatContainer)\n\n // FIXME: check the Why value on this quad:\n const chatAclDoc = store.any(\n chatContainer,\n new NamedNode('http://www.iana.org/assignments/link-relations/acl')\n )\n if (!chatAclDoc) {\n throw new Error('Chat ACL doc not found!')\n }\n\n const aclBody = `\n @prefix acl: <http://www.w3.org/ns/auth/acl#>.\n <#owner>\n a acl:Authorization;\n acl:agent <${me.value}>;\n acl:accessTo <.>;\n acl:default <.>;\n acl:mode\n acl:Read, acl:Write, acl:Control.\n <#invitee>\n a acl:Authorization;\n acl:agent <${invitee.value}>;\n acl:accessTo <.>;\n acl:default <.>;\n acl:mode\n acl:Read, acl:Append.\n `\n await store.fetcher.webOperation('PUT', chatAclDoc.value, {\n data: aclBody,\n contentType: 'text/turtle',\n })\n }\n\n async function addToPrivateTypeIndex(chatThing, me) {\n // Add to private type index\n const privateTypeIndex = store.any(\n me,\n ns.solid('privateTypeIndex')\n ) as NamedNode | null\n if (!privateTypeIndex) {\n throw new Error('Private type index not found!')\n }\n await store.fetcher.load(privateTypeIndex)\n const reg = newThing(privateTypeIndex)\n const ins = [\n st(\n reg,\n ns.rdf('type'),\n ns.solid('TypeRegistration'),\n privateTypeIndex.doc()\n ),\n st(\n reg,\n ns.solid('forClass'),\n ns.meeting('LongChat'),\n privateTypeIndex.doc()\n ),\n st(reg, ns.solid('instance'), chatThing, privateTypeIndex.doc()),\n ]\n await new Promise((resolve, reject) => {\n store.updater.update([], ins, function (_uri, ok, errm) {\n if (!ok) {\n reject(new Error(errm))\n } else {\n resolve(null)\n }\n })\n })\n }\n\n async function findChat(invitee: NamedNode): Promise<Chat> {\n const me = await profileLogic.loadMe()\n const podRoot = await profileLogic.getPodRoot(me)\n const chatContainer = determineChatContainer(invitee, podRoot)\n let exists = true\n try {\n await store.fetcher.load(\n new NamedNode(chatContainer.value + 'index.ttl#this')\n )\n } catch (e) {\n exists = false\n }\n return { me, chatContainer, exists }\n }\n\n async function createChatThing(\n chatContainer: NamedNode,\n me: NamedNode\n ): Promise<NamedNode> {\n const created = await mintNew({\n me,\n newBase: chatContainer.value,\n })\n return created.newInstance\n }\n\n function mintNew(newPaneOptions: NewPaneOptions): Promise<CreatedPaneOptions> {\n const kb = store\n const updater = kb.updater\n if (newPaneOptions.me && !newPaneOptions.me.uri) {\n throw new Error('chat mintNew: Invalid userid ' + newPaneOptions.me)\n }\n\n const newInstance = (newPaneOptions.newInstance =\n newPaneOptions.newInstance ||\n kb.sym(newPaneOptions.newBase + CHAT_LOCATION_IN_CONTAINER))\n const newChatDoc = newInstance.doc()\n\n kb.add(\n newInstance,\n ns.rdf('type'),\n ns.meeting('LongChat'),\n newChatDoc\n )\n kb.add(newInstance, ns.dc('title'), 'Chat channel', newChatDoc)\n kb.add(\n newInstance,\n ns.dc('created'),\n term<Node>(new Date(Date.now())),\n newChatDoc\n )\n if (newPaneOptions.me) {\n kb.add(newInstance, ns.dc('author'), newPaneOptions.me, newChatDoc)\n }\n\n return new Promise(function (resolve, reject) {\n updater?.put(\n newChatDoc,\n kb.statementsMatching(undefined, undefined, undefined, newChatDoc),\n 'text/turtle',\n function (uri2, ok, message) {\n if (ok) {\n resolve({\n ...newPaneOptions,\n newInstance,\n })\n } else {\n reject(\n new Error(\n 'FAILED to save new chat channel at: ' + uri2 + ' : ' + message\n )\n )\n }\n }\n )\n })\n }\n\n /**\n * Find (and optionally create) an individual chat between the current user and the given invitee\n * @param invitee - The person to chat with\n * @param createIfMissing - Whether the chat should be created, if missing\n * @returns null if missing, or a node referring to an already existing chat, or the newly created chat\n */\n async function getChat(\n invitee: NamedNode,\n createIfMissing = true\n ): Promise<NamedNode | null> {\n const { me, chatContainer, exists } = await findChat(invitee)\n if (exists) {\n return new NamedNode(chatContainer.value + CHAT_LOCATION_IN_CONTAINER)\n }\n\n if (createIfMissing) {\n const chatThing = await createChatThing(chatContainer, me)\n await sendInvite(invitee, chatThing)\n await setAcl(chatContainer, me, invitee)\n await addToPrivateTypeIndex(chatThing, me)\n return chatThing\n }\n return null\n }\n\n async function sendInvite(invitee: NamedNode, chatThing: NamedNode) {\n await store.fetcher.load(invitee.doc())\n const inviteeInbox = store.any(\n invitee,\n ns.ldp('inbox'),\n undefined,\n invitee.doc()\n )\n if (!inviteeInbox) {\n throw new Error(`Invitee inbox not found! ${invitee.value}`)\n }\n const inviteBody = `\n <> a <http://www.w3.org/ns/pim/meeting#LongChatInvite> ;\n ${ns.rdf('seeAlso')} <${chatThing.value}> .\n `\n\n const inviteResponse = await store.fetcher?.webOperation(\n 'POST',\n inviteeInbox.value,\n {\n data: inviteBody,\n contentType: 'text/turtle',\n }\n )\n const locationStr = inviteResponse?.headers.get('location')\n if (!locationStr) {\n throw new Error(`Invite sending returned a ${inviteResponse?.status}`)\n }\n }\n return {\n setAcl, addToPrivateTypeIndex, findChat, createChatThing, getChat, sendInvite, mintNew\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { ns as e } from "../util/ns.esm.js";
|
|
2
|
-
import { determineChatContainer as t, newThing as n } from "../util/utils.esm.js";
|
|
3
|
-
import { NamedNode as r, st as i, term as a } from "rdflib";
|
|
4
|
-
//#region src/chat/chatLogic.ts
|
|
5
|
-
var o = "index.ttl#this";
|
|
6
|
-
function s(s, c) {
|
|
7
|
-
let l = e;
|
|
8
|
-
async function u(e, t, n) {
|
|
9
|
-
await s.fetcher.load(e);
|
|
10
|
-
let i = s.any(e, new r("http://www.iana.org/assignments/link-relations/acl"));
|
|
11
|
-
if (!i) throw Error("Chat ACL doc not found!");
|
|
12
|
-
let a = `
|
|
13
|
-
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
|
|
14
|
-
<#owner>
|
|
15
|
-
a acl:Authorization;
|
|
16
|
-
acl:agent <${t.value}>;
|
|
17
|
-
acl:accessTo <.>;
|
|
18
|
-
acl:default <.>;
|
|
19
|
-
acl:mode
|
|
20
|
-
acl:Read, acl:Write, acl:Control.
|
|
21
|
-
<#invitee>
|
|
22
|
-
a acl:Authorization;
|
|
23
|
-
acl:agent <${n.value}>;
|
|
24
|
-
acl:accessTo <.>;
|
|
25
|
-
acl:default <.>;
|
|
26
|
-
acl:mode
|
|
27
|
-
acl:Read, acl:Append.
|
|
28
|
-
`;
|
|
29
|
-
await s.fetcher.webOperation("PUT", i.value, {
|
|
30
|
-
data: a,
|
|
31
|
-
contentType: "text/turtle"
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
async function d(e, t) {
|
|
35
|
-
let r = s.any(t, l.solid("privateTypeIndex"));
|
|
36
|
-
if (!r) throw Error("Private type index not found!");
|
|
37
|
-
await s.fetcher.load(r);
|
|
38
|
-
let a = n(r), o = [
|
|
39
|
-
i(a, l.rdf("type"), l.solid("TypeRegistration"), r.doc()),
|
|
40
|
-
i(a, l.solid("forClass"), l.meeting("LongChat"), r.doc()),
|
|
41
|
-
i(a, l.solid("instance"), e, r.doc())
|
|
42
|
-
];
|
|
43
|
-
await new Promise((e, t) => {
|
|
44
|
-
s.updater.update([], o, function(n, r, i) {
|
|
45
|
-
r ? e(null) : t(Error(i));
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
async function f(e) {
|
|
50
|
-
let n = await c.loadMe(), i = t(e, await c.getPodRoot(n)), a = !0;
|
|
51
|
-
try {
|
|
52
|
-
await s.fetcher.load(new r(i.value + "index.ttl#this"));
|
|
53
|
-
} catch {
|
|
54
|
-
a = !1;
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
me: n,
|
|
58
|
-
chatContainer: i,
|
|
59
|
-
exists: a
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
async function p(e, t) {
|
|
63
|
-
return (await m({
|
|
64
|
-
me: t,
|
|
65
|
-
newBase: e.value
|
|
66
|
-
})).newInstance;
|
|
67
|
-
}
|
|
68
|
-
function m(e) {
|
|
69
|
-
let t = s, n = t.updater;
|
|
70
|
-
if (e.me && !e.me.uri) throw Error("chat mintNew: Invalid userid " + e.me);
|
|
71
|
-
let r = e.newInstance = e.newInstance || t.sym(e.newBase + o), i = r.doc();
|
|
72
|
-
return t.add(r, l.rdf("type"), l.meeting("LongChat"), i), t.add(r, l.dc("title"), "Chat channel", i), t.add(r, l.dc("created"), a(new Date(Date.now())), i), e.me && t.add(r, l.dc("author"), e.me, i), new Promise(function(a, o) {
|
|
73
|
-
n?.put(i, t.statementsMatching(void 0, void 0, void 0, i), "text/turtle", function(t, n, i) {
|
|
74
|
-
n ? a({
|
|
75
|
-
...e,
|
|
76
|
-
newInstance: r
|
|
77
|
-
}) : o(/* @__PURE__ */ Error("FAILED to save new chat channel at: " + t + " : " + i));
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
async function h(e, t = !0) {
|
|
82
|
-
let { me: n, chatContainer: i, exists: a } = await f(e);
|
|
83
|
-
if (a) return new r(i.value + o);
|
|
84
|
-
if (t) {
|
|
85
|
-
let t = await p(i, n);
|
|
86
|
-
return await g(e, t), await u(i, n, e), await d(t, n), t;
|
|
87
|
-
}
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
async function g(e, t) {
|
|
91
|
-
await s.fetcher.load(e.doc());
|
|
92
|
-
let n = s.any(e, l.ldp("inbox"), void 0, e.doc());
|
|
93
|
-
if (!n) throw Error(`Invitee inbox not found! ${e.value}`);
|
|
94
|
-
let r = `
|
|
95
|
-
<> a <http://www.w3.org/ns/pim/meeting#LongChatInvite> ;
|
|
96
|
-
${l.rdf("seeAlso")} <${t.value}> .
|
|
97
|
-
`, i = await s.fetcher?.webOperation("POST", n.value, {
|
|
98
|
-
data: r,
|
|
99
|
-
contentType: "text/turtle"
|
|
100
|
-
});
|
|
101
|
-
if (!i?.headers.get("location")) throw Error(`Invite sending returned a ${i?.status}`);
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
setAcl: u,
|
|
105
|
-
addToPrivateTypeIndex: d,
|
|
106
|
-
findChat: f,
|
|
107
|
-
createChatThing: p,
|
|
108
|
-
getChat: h,
|
|
109
|
-
sendInvite: g,
|
|
110
|
-
mintNew: m
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
//#endregion
|
|
114
|
-
export { s as createChatLogic };
|
|
115
|
-
|
|
116
|
-
//# sourceMappingURL=chatLogic.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chatLogic.esm.js","names":[],"sources":["../../src/chat/chatLogic.ts"],"sourcesContent":["import { NamedNode, Node, st, term } from 'rdflib'\nimport { ChatLogic, CreatedPaneOptions, NewPaneOptions, Chat } from '../types'\nimport { ns as namespace } from '../util/ns'\nimport { determineChatContainer, newThing } from '../util/utils'\n\nconst CHAT_LOCATION_IN_CONTAINER = 'index.ttl#this'\n\nexport function createChatLogic(store, profileLogic): ChatLogic {\n const ns = namespace\n\n async function setAcl(\n chatContainer: NamedNode,\n me: NamedNode,\n invitee: NamedNode\n ): Promise<void> {\n // Some servers don't present a Link http response header\n // if the container doesn't exist yet, so refetch the container\n // now that it has been created:\n await store.fetcher.load(chatContainer)\n\n // FIXME: check the Why value on this quad:\n const chatAclDoc = store.any(\n chatContainer,\n new NamedNode('http://www.iana.org/assignments/link-relations/acl')\n )\n if (!chatAclDoc) {\n throw new Error('Chat ACL doc not found!')\n }\n\n const aclBody = `\n @prefix acl: <http://www.w3.org/ns/auth/acl#>.\n <#owner>\n a acl:Authorization;\n acl:agent <${me.value}>;\n acl:accessTo <.>;\n acl:default <.>;\n acl:mode\n acl:Read, acl:Write, acl:Control.\n <#invitee>\n a acl:Authorization;\n acl:agent <${invitee.value}>;\n acl:accessTo <.>;\n acl:default <.>;\n acl:mode\n acl:Read, acl:Append.\n `\n await store.fetcher.webOperation('PUT', chatAclDoc.value, {\n data: aclBody,\n contentType: 'text/turtle',\n })\n }\n\n async function addToPrivateTypeIndex(chatThing, me) {\n // Add to private type index\n const privateTypeIndex = store.any(\n me,\n ns.solid('privateTypeIndex')\n ) as NamedNode | null\n if (!privateTypeIndex) {\n throw new Error('Private type index not found!')\n }\n await store.fetcher.load(privateTypeIndex)\n const reg = newThing(privateTypeIndex)\n const ins = [\n st(\n reg,\n ns.rdf('type'),\n ns.solid('TypeRegistration'),\n privateTypeIndex.doc()\n ),\n st(\n reg,\n ns.solid('forClass'),\n ns.meeting('LongChat'),\n privateTypeIndex.doc()\n ),\n st(reg, ns.solid('instance'), chatThing, privateTypeIndex.doc()),\n ]\n await new Promise((resolve, reject) => {\n store.updater.update([], ins, function (_uri, ok, errm) {\n if (!ok) {\n reject(new Error(errm))\n } else {\n resolve(null)\n }\n })\n })\n }\n\n async function findChat(invitee: NamedNode): Promise<Chat> {\n const me = await profileLogic.loadMe()\n const podRoot = await profileLogic.getPodRoot(me)\n const chatContainer = determineChatContainer(invitee, podRoot)\n let exists = true\n try {\n await store.fetcher.load(\n new NamedNode(chatContainer.value + 'index.ttl#this')\n )\n } catch (e) {\n exists = false\n }\n return { me, chatContainer, exists }\n }\n\n async function createChatThing(\n chatContainer: NamedNode,\n me: NamedNode\n ): Promise<NamedNode> {\n const created = await mintNew({\n me,\n newBase: chatContainer.value,\n })\n return created.newInstance\n }\n\n function mintNew(newPaneOptions: NewPaneOptions): Promise<CreatedPaneOptions> {\n const kb = store\n const updater = kb.updater\n if (newPaneOptions.me && !newPaneOptions.me.uri) {\n throw new Error('chat mintNew: Invalid userid ' + newPaneOptions.me)\n }\n\n const newInstance = (newPaneOptions.newInstance =\n newPaneOptions.newInstance ||\n kb.sym(newPaneOptions.newBase + CHAT_LOCATION_IN_CONTAINER))\n const newChatDoc = newInstance.doc()\n\n kb.add(\n newInstance,\n ns.rdf('type'),\n ns.meeting('LongChat'),\n newChatDoc\n )\n kb.add(newInstance, ns.dc('title'), 'Chat channel', newChatDoc)\n kb.add(\n newInstance,\n ns.dc('created'),\n term<Node>(new Date(Date.now())),\n newChatDoc\n )\n if (newPaneOptions.me) {\n kb.add(newInstance, ns.dc('author'), newPaneOptions.me, newChatDoc)\n }\n\n return new Promise(function (resolve, reject) {\n updater?.put(\n newChatDoc,\n kb.statementsMatching(undefined, undefined, undefined, newChatDoc),\n 'text/turtle',\n function (uri2, ok, message) {\n if (ok) {\n resolve({\n ...newPaneOptions,\n newInstance,\n })\n } else {\n reject(\n new Error(\n 'FAILED to save new chat channel at: ' + uri2 + ' : ' + message\n )\n )\n }\n }\n )\n })\n }\n\n /**\n * Find (and optionally create) an individual chat between the current user and the given invitee\n * @param invitee - The person to chat with\n * @param createIfMissing - Whether the chat should be created, if missing\n * @returns null if missing, or a node referring to an already existing chat, or the newly created chat\n */\n async function getChat(\n invitee: NamedNode,\n createIfMissing = true\n ): Promise<NamedNode | null> {\n const { me, chatContainer, exists } = await findChat(invitee)\n if (exists) {\n return new NamedNode(chatContainer.value + CHAT_LOCATION_IN_CONTAINER)\n }\n\n if (createIfMissing) {\n const chatThing = await createChatThing(chatContainer, me)\n await sendInvite(invitee, chatThing)\n await setAcl(chatContainer, me, invitee)\n await addToPrivateTypeIndex(chatThing, me)\n return chatThing\n }\n return null\n }\n\n async function sendInvite(invitee: NamedNode, chatThing: NamedNode) {\n await store.fetcher.load(invitee.doc())\n const inviteeInbox = store.any(\n invitee,\n ns.ldp('inbox'),\n undefined,\n invitee.doc()\n )\n if (!inviteeInbox) {\n throw new Error(`Invitee inbox not found! ${invitee.value}`)\n }\n const inviteBody = `\n <> a <http://www.w3.org/ns/pim/meeting#LongChatInvite> ;\n ${ns.rdf('seeAlso')} <${chatThing.value}> .\n `\n\n const inviteResponse = await store.fetcher?.webOperation(\n 'POST',\n inviteeInbox.value,\n {\n data: inviteBody,\n contentType: 'text/turtle',\n }\n )\n const locationStr = inviteResponse?.headers.get('location')\n if (!locationStr) {\n throw new Error(`Invite sending returned a ${inviteResponse?.status}`)\n }\n }\n return {\n setAcl, addToPrivateTypeIndex, findChat, createChatThing, getChat, sendInvite, mintNew\n }\n}\n"],"mappings":"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"}
|