forked from SolidOS/solid-panes
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbasicPreferences.source.ts
More file actions
122 lines (104 loc) · 4.58 KB
/
Copy pathbasicPreferences.source.ts
File metadata and controls
122 lines (104 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { PaneDefinition } from '../types'
import UI from 'solid-ui'
import namespace from 'solid-namespace'
import { NamedNode, parse, namedNode, IndexedFormula } from 'rdflib'
import { renderTrustedApplicationsOptions } from './trustedApplications/trustedApplicationsPane'
import preferencesFormText from './preferencesFormText.ttl'
import ontologyData from './ontologyData.ttl'
const kb = UI.store
const ns = namespace({ namedNode } as any)
export const basicPreferencesPane: PaneDefinition = {
icon: UI.icons.iconBase + 'noun_Sliders_341315_000000.svg',
name: 'basicPreferences',
label: (_subject) => {
return null
},
// Render the pane
// The subject should be the logged in user.
render: (subject: NamedNode, dom: HTMLDocument) => {
function complainIfBad (ok: Boolean, mess: any) {
if (ok) return
container.appendChild(UI.widgets.errorMessageBlock(dom, mess, '#fee'))
}
const container = dom.createElement('div')
const formArea = container.appendChild(dom.createElement('div'))
function loadData (doc: NamedNode, turtle: String) {
doc = doc.doc() // remove # from URI if nec
if (!kb.holds(undefined, undefined, undefined, doc)) { // If not loaded already
(parse as any)(turtle, kb, doc.uri, 'text/turtle', null) // Load form directly
}
}
const preferencesForm = kb.sym('urn:uuid:93774ba1-d3b6-41f2-85b6-4ae27ffd2597#this')
loadData(preferencesForm, preferencesFormText)
const ontologyExtra = kb.sym('urn:uuid:93774ba1-d3b6-41f2-85b6-4ae27ffd2597-ONT')
loadData(ontologyExtra, ontologyData)
async function doRender () {
const context = await UI.authn.logInLoadPreferences({ dom, div: container })
if (!context.preferencesFile) { // Could be CORS
console.log('Not doing private class preferences as no access to preferences file. ' + context.preferencesFileError)
return
}
addDeletionLinks(container, kb, context.me)
const appendedForm = UI.widgets.appendForm(dom, formArea, {}, context.me, preferencesForm, context.preferencesFile, complainIfBad)
appendedForm.style.borderStyle = 'none'
const trustedApplicationSettings = renderTrustedApplicationsOptions(dom)
container.appendChild(trustedApplicationSettings)
}
doRender()
return container
}
}
export default basicPreferencesPane
// ends
function addDeletionLinks (container: HTMLElement, kb: IndexedFormula, profile: NamedNode): void {
const podServerNodes = kb.each(profile, ns.space('storage'), null, profile.doc())
const podServers = podServerNodes.map(node => node.value)
podServers.forEach(async (server) => {
const deletionLink = await generateDeletionLink(server)
if (deletionLink) {
container.appendChild(deletionLink)
}
})
}
async function generateDeletionLink (podServer: string): Promise<HTMLElement | null> {
const link = document.createElement('a')
link.textContent = `Delete your account at ${podServer}`
const deletionUrl = await getDeletionUrlForServer(podServer)
if (typeof deletionUrl !== 'string') {
return null
}
link.href = deletionUrl
return link
}
/**
* Hacky way to get the deletion link to a Pod
*
* This function infers the deletion link by assuming the URL structure of Node Solid server.
* In the future, Solid will hopefully provide a standardised way of discovering the deletion link:
* https://github.com/solid/data-interoperability-panel/issues/18
*
* If NSS is in multi-user mode (the case on inrupt.net and solid.community), the deletion URL for
* vincent.dev.inrupt.net would be at dev.inrupt.net/account/delete. In single-user mode, the
* deletion URL would be at vincent.dev.inrupt.net/account/delete.
*
* @param server Pod server containing the user's account.
* @returns URL of the page that Node Solid Server would offer to delete the account, or null if
* the URLs we tried give invalid responses.
*/
async function getDeletionUrlForServer (server: string): Promise<string | null> {
const singleUserUrl = new url(server)
const multiUserUrl = new url(server)
multiUserUrl.pathname = singleUserUrl.pathname = '/account/delete'
const hostnameParts = multiUserUrl.hostname.split('.')
// Remove `vincent.` from `vincent.dev.inrupt.net`, for example:
multiUserUrl.hostname = hostnameParts.slice(1).join('.')
const multiUserNssResponse = await fetch(multiUserUrl.href, { method: 'HEAD' })
if (multiUserNssResponse.ok) {
return multiUserUrl.href
}
const singleUserNssResponse = await fetch(singleUserUrl.href, { method: 'HEAD' })
if (singleUserNssResponse.ok) {
return singleUserUrl.href
}
return null
}