solid-server 5.6.9-beta

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 (170) hide show
  1. package/.acl +10 -0
  2. package/.github/workflows/ci.yml +47 -0
  3. package/.nvmrc +1 -0
  4. package/.snyk +35 -0
  5. package/.well-known/.acl +15 -0
  6. package/CHANGELOG.md +198 -0
  7. package/CONTRIBUTING.md +139 -0
  8. package/CONTRIBUTORS.md +36 -0
  9. package/Dockerfile +22 -0
  10. package/LICENSE.md +23 -0
  11. package/README.md +453 -0
  12. package/bin/lib/cli-utils.js +85 -0
  13. package/bin/lib/cli.js +39 -0
  14. package/bin/lib/init.js +94 -0
  15. package/bin/lib/invalidUsernames.js +148 -0
  16. package/bin/lib/migrateLegacyResources.js +69 -0
  17. package/bin/lib/options.js +399 -0
  18. package/bin/lib/start.js +148 -0
  19. package/bin/lib/updateIndex.js +56 -0
  20. package/bin/solid +3 -0
  21. package/bin/solid-test +12 -0
  22. package/bin/solid.js +3 -0
  23. package/common/css/solid.css +58 -0
  24. package/common/fonts/glyphicons-halflings-regular.eot +0 -0
  25. package/common/fonts/glyphicons-halflings-regular.svg +288 -0
  26. package/common/fonts/glyphicons-halflings-regular.ttf +0 -0
  27. package/common/fonts/glyphicons-halflings-regular.woff +0 -0
  28. package/common/fonts/glyphicons-halflings-regular.woff2 +0 -0
  29. package/common/img/.gitkeep +0 -0
  30. package/common/js/auth-buttons.js +65 -0
  31. package/common/js/solid.js +454 -0
  32. package/common/well-known/security.txt +2 -0
  33. package/config/defaults.js +25 -0
  34. package/config/usernames-blacklist.json +4 -0
  35. package/config.json-default +22 -0
  36. package/default-templates/emails/delete-account.js +49 -0
  37. package/default-templates/emails/invalid-username.js +30 -0
  38. package/default-templates/emails/reset-password.js +49 -0
  39. package/default-templates/emails/welcome.js +39 -0
  40. package/default-templates/new-account/.acl +26 -0
  41. package/default-templates/new-account/.meta +5 -0
  42. package/default-templates/new-account/.meta.acl +25 -0
  43. package/default-templates/new-account/.well-known/.acl +19 -0
  44. package/default-templates/new-account/favicon.ico +0 -0
  45. package/default-templates/new-account/favicon.ico.acl +26 -0
  46. package/default-templates/new-account/inbox/.acl +26 -0
  47. package/default-templates/new-account/private/.acl +10 -0
  48. package/default-templates/new-account/profile/.acl +19 -0
  49. package/default-templates/new-account/profile/card$.ttl +25 -0
  50. package/default-templates/new-account/public/.acl +19 -0
  51. package/default-templates/new-account/robots.txt +3 -0
  52. package/default-templates/new-account/robots.txt.acl +26 -0
  53. package/default-templates/new-account/settings/.acl +20 -0
  54. package/default-templates/new-account/settings/prefs.ttl +15 -0
  55. package/default-templates/new-account/settings/privateTypeIndex.ttl +4 -0
  56. package/default-templates/new-account/settings/publicTypeIndex.ttl +4 -0
  57. package/default-templates/new-account/settings/publicTypeIndex.ttl.acl +25 -0
  58. package/default-templates/new-account/settings/serverSide.ttl.acl +13 -0
  59. package/default-templates/new-account/settings/serverSide.ttl.inactive +12 -0
  60. package/default-templates/server/.acl +10 -0
  61. package/default-templates/server/.well-known/.acl +15 -0
  62. package/default-templates/server/favicon.ico +0 -0
  63. package/default-templates/server/favicon.ico.acl +15 -0
  64. package/default-templates/server/index.html +55 -0
  65. package/default-templates/server/robots.txt +3 -0
  66. package/default-templates/server/robots.txt.acl +15 -0
  67. package/default-views/account/account-deleted.hbs +17 -0
  68. package/default-views/account/delete-confirm.hbs +51 -0
  69. package/default-views/account/delete-link-sent.hbs +17 -0
  70. package/default-views/account/delete.hbs +51 -0
  71. package/default-views/account/invalid-username.hbs +22 -0
  72. package/default-views/account/register-disabled.hbs +6 -0
  73. package/default-views/account/register-form.hbs +132 -0
  74. package/default-views/account/register.hbs +24 -0
  75. package/default-views/auth/auth-hidden-fields.hbs +8 -0
  76. package/default-views/auth/change-password.hbs +58 -0
  77. package/default-views/auth/goodbye.hbs +23 -0
  78. package/default-views/auth/login-required.hbs +34 -0
  79. package/default-views/auth/login-tls.hbs +11 -0
  80. package/default-views/auth/login-username-password.hbs +28 -0
  81. package/default-views/auth/login.hbs +55 -0
  82. package/default-views/auth/no-permission.hbs +29 -0
  83. package/default-views/auth/password-changed.hbs +27 -0
  84. package/default-views/auth/reset-link-sent.hbs +21 -0
  85. package/default-views/auth/reset-password.hbs +52 -0
  86. package/default-views/auth/sharing.hbs +49 -0
  87. package/default-views/shared/create-account.hbs +8 -0
  88. package/default-views/shared/error.hbs +5 -0
  89. package/docs/how-to-delete-your-account.md +56 -0
  90. package/docs/login-and-grant-access-to-application.md +32 -0
  91. package/examples/custom-error-handling.js +31 -0
  92. package/examples/ldp-with-webid.js +12 -0
  93. package/examples/simple-express-app.js +20 -0
  94. package/examples/simple-ldp-server.js +8 -0
  95. package/favicon.ico +0 -0
  96. package/favicon.ico.acl +15 -0
  97. package/index.html +48 -0
  98. package/index.js +3 -0
  99. package/lib/acl-checker.js +274 -0
  100. package/lib/api/accounts/user-accounts.js +88 -0
  101. package/lib/api/authn/force-user.js +21 -0
  102. package/lib/api/authn/index.js +5 -0
  103. package/lib/api/authn/webid-oidc.js +202 -0
  104. package/lib/api/authn/webid-tls.js +69 -0
  105. package/lib/api/index.js +6 -0
  106. package/lib/capability-discovery.js +54 -0
  107. package/lib/common/fs-utils.js +43 -0
  108. package/lib/common/template-utils.js +50 -0
  109. package/lib/common/user-utils.js +28 -0
  110. package/lib/create-app.js +322 -0
  111. package/lib/create-server.js +107 -0
  112. package/lib/debug.js +17 -0
  113. package/lib/handlers/allow.js +82 -0
  114. package/lib/handlers/auth-proxy.js +63 -0
  115. package/lib/handlers/copy.js +39 -0
  116. package/lib/handlers/cors-proxy.js +95 -0
  117. package/lib/handlers/delete.js +23 -0
  118. package/lib/handlers/error-pages.js +212 -0
  119. package/lib/handlers/get.js +219 -0
  120. package/lib/handlers/index.js +42 -0
  121. package/lib/handlers/options.js +33 -0
  122. package/lib/handlers/patch/n3-patch-parser.js +49 -0
  123. package/lib/handlers/patch/sparql-update-parser.js +16 -0
  124. package/lib/handlers/patch.js +203 -0
  125. package/lib/handlers/post.js +99 -0
  126. package/lib/handlers/put.js +56 -0
  127. package/lib/handlers/restrict-to-top-domain.js +13 -0
  128. package/lib/header.js +136 -0
  129. package/lib/http-error.js +34 -0
  130. package/lib/ldp-container.js +161 -0
  131. package/lib/ldp-copy.js +73 -0
  132. package/lib/ldp-middleware.js +32 -0
  133. package/lib/ldp.js +620 -0
  134. package/lib/lock.js +10 -0
  135. package/lib/metadata.js +10 -0
  136. package/lib/models/account-manager.js +603 -0
  137. package/lib/models/account-template.js +152 -0
  138. package/lib/models/authenticator.js +333 -0
  139. package/lib/models/oidc-manager.js +53 -0
  140. package/lib/models/solid-host.js +131 -0
  141. package/lib/models/user-account.js +112 -0
  142. package/lib/models/webid-tls-certificate.js +184 -0
  143. package/lib/payment-pointer-discovery.js +83 -0
  144. package/lib/requests/add-cert-request.js +138 -0
  145. package/lib/requests/auth-request.js +234 -0
  146. package/lib/requests/create-account-request.js +468 -0
  147. package/lib/requests/delete-account-confirm-request.js +170 -0
  148. package/lib/requests/delete-account-request.js +144 -0
  149. package/lib/requests/login-request.js +205 -0
  150. package/lib/requests/password-change-request.js +201 -0
  151. package/lib/requests/password-reset-email-request.js +199 -0
  152. package/lib/requests/sharing-request.js +259 -0
  153. package/lib/resource-mapper.js +198 -0
  154. package/lib/server-config.js +167 -0
  155. package/lib/services/blacklist-service.js +33 -0
  156. package/lib/services/email-service.js +162 -0
  157. package/lib/services/token-service.js +47 -0
  158. package/lib/utils.js +254 -0
  159. package/lib/webid/index.js +13 -0
  160. package/lib/webid/lib/get.js +27 -0
  161. package/lib/webid/lib/parse.js +12 -0
  162. package/lib/webid/tls/index.js +185 -0
  163. package/package.json +172 -0
  164. package/renovate.json +5 -0
  165. package/robots.txt +3 -0
  166. package/robots.txt.acl +15 -0
  167. package/static/account-recovery.html +78 -0
  168. package/static/popup-redirect.html +1 -0
  169. package/static/signup.html +108 -0
  170. package/static/signup.html.acl +14 -0
@@ -0,0 +1,12 @@
1
+ module.exports = parse
2
+
3
+ const $rdf = require('rdflib')
4
+
5
+ function parse (profile, graph, uri, mimeType, callback) {
6
+ try {
7
+ $rdf.parse(profile, graph, uri, mimeType)
8
+ return callback(null, graph)
9
+ } catch (e) {
10
+ return callback(new Error('Could not load/parse profile data: ' + e))
11
+ }
12
+ }
@@ -0,0 +1,185 @@
1
+ exports.verify = verify
2
+ exports.generate = generate
3
+ exports.verifyKey = verifyKey
4
+
5
+ const $rdf = require('rdflib')
6
+ const get = require('../lib/get')
7
+ const parse = require('../lib/parse')
8
+ const forge = require('node-forge')
9
+ const url = require('url')
10
+ const crypto = require('crypto')
11
+ const certificate = new crypto.Certificate()
12
+ const pki = forge.pki
13
+ const Graph = $rdf.graph
14
+ const SPARQL_QUERY = 'PREFIX cert: <http://www.w3.org/ns/auth/cert#> SELECT ?webid ?m ?e WHERE { ?webid cert:key ?key . ?key cert:modulus ?m . ?key cert:exponent ?e . }'
15
+
16
+ function verify (certificate, callback) {
17
+ if (!certificate) {
18
+ return callback(new Error('No certificate given'))
19
+ }
20
+
21
+ // Collect URIs in certificate
22
+ const uris = getUris(certificate)
23
+
24
+ // No uris
25
+ if (uris.length === 0) {
26
+ return callback(new Error('Empty Subject Alternative Name field in certificate'))
27
+ }
28
+
29
+ // Get first URI
30
+ const uri = uris.shift()
31
+ get(uri, function (err, body, contentType) {
32
+ if (err) {
33
+ return callback(err)
34
+ }
35
+
36
+ // Verify Key
37
+ verifyKey(certificate, uri, body, contentType, function (err, success) {
38
+ return callback(err, uri)
39
+ })
40
+ })
41
+ }
42
+
43
+ function getUris (certificate) {
44
+ const uris = []
45
+
46
+ if (certificate && certificate.subjectaltname) {
47
+ certificate
48
+ .subjectaltname
49
+ .replace(/URI:([^, ]+)/g, function (match, uri) {
50
+ return uris.push(uri)
51
+ })
52
+ }
53
+ return uris
54
+ }
55
+
56
+ function verifyKey (certificate, uri, profile, contentType, callback) {
57
+ const graph = new Graph()
58
+ let found = false
59
+
60
+ if (!certificate.modulus) {
61
+ return callback(new Error('Missing modulus value in client certificate'))
62
+ }
63
+
64
+ if (!certificate.exponent) {
65
+ return callback(new Error('Missing exponent value in client certificate'))
66
+ }
67
+
68
+ if (!contentType) {
69
+ return callback(new Error('No value specified for the Content-Type header'))
70
+ }
71
+
72
+ const mimeType = contentType.replace(/;.*/, '')
73
+ parse(profile, graph, uri, mimeType, function (err) {
74
+ if (err) {
75
+ return callback(err)
76
+ }
77
+ const certExponent = parseInt(certificate.exponent, 16).toString()
78
+ const query = $rdf.SPARQLToQuery(SPARQL_QUERY, undefined, graph)
79
+ graph.query(
80
+ query,
81
+ function (result) {
82
+ if (found) {
83
+ return
84
+ }
85
+ const modulus = result['?m'].value
86
+ const exponent = result['?e'].value
87
+
88
+ if (modulus != null &&
89
+ exponent != null &&
90
+ (modulus.toLowerCase() === certificate.modulus.toLowerCase()) &&
91
+ exponent === certExponent) {
92
+ found = true
93
+ }
94
+ },
95
+ undefined, // testing
96
+ function () {
97
+ if (!found) {
98
+ return callback(new Error('Certificate public key not found in the user\'s profile'))
99
+ }
100
+ return callback(null, true)
101
+ }
102
+ )
103
+ })
104
+ }
105
+
106
+ function generate (options, callback) {
107
+ if (!options.agent) {
108
+ return callback(new Error('No agent uri found'))
109
+ }
110
+ if (!options.spkac) {
111
+ return callback(new Error('No public key found'), null)
112
+ }
113
+ if (!certificate.verifySpkac(Buffer.from(options.spkac))) {
114
+ return callback(new Error('Invalid SPKAC'))
115
+ }
116
+ options.duration = options.duration || 10
117
+
118
+ // Generate a new certificate
119
+ const cert = pki.createCertificate()
120
+ cert.serialNumber = (Date.now()).toString(16)
121
+
122
+ // Get fields from SPKAC to populate new cert
123
+ const publicKey = certificate.exportPublicKey(options.spkac).toString()
124
+ cert.publicKey = pki.publicKeyFromPem(publicKey)
125
+
126
+ // Validity of 10 years
127
+ cert.validity.notBefore = new Date()
128
+ cert.validity.notAfter = new Date()
129
+ cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + options.duration)
130
+
131
+ // `.` is default with the OpenSSL command line tool
132
+ const commonName = options.commonName || url.URL(options.agent).hostname
133
+ const attrsSubject = [{
134
+ name: 'commonName',
135
+ value: commonName
136
+ }, {
137
+ name: 'organizationName',
138
+ value: options.organizationName || 'WebID'
139
+ }]
140
+
141
+ const attrsIssuer = [{
142
+ name: 'commonName',
143
+ value: commonName
144
+ }, {
145
+ name: 'organizationName',
146
+ value: options.organizationName || 'WebID'
147
+ }]
148
+
149
+ if (options.issuer) {
150
+ if (options.issuer.commonName) {
151
+ attrsIssuer[0].value = options.issuer.commonName
152
+ }
153
+ if (options.issuer.organizationName) {
154
+ attrsIssuer[1].value = options.issuer.organizationName
155
+ }
156
+ }
157
+
158
+ // Set same fields for certificate and issuer
159
+ cert.setSubject(attrsSubject)
160
+ cert.setIssuer(attrsIssuer)
161
+
162
+ // Set the cert extensions
163
+ cert.setExtensions([
164
+ {
165
+ name: 'basicConstraints',
166
+ cA: false,
167
+ critical: true
168
+ }, {
169
+ name: 'subjectAltName',
170
+ altNames: [{
171
+ type: 6, // URI
172
+ value: options.agent
173
+ }]
174
+ }, {
175
+ name: 'subjectKeyIdentifier'
176
+ }
177
+ ])
178
+
179
+ // Generate a new keypair to sign the certificate
180
+ // TODO this make is not really "self-signed"
181
+ const keys = pki.rsa.generateKeyPair(1024)
182
+ cert.sign(keys.privateKey, forge.md.sha256.create())
183
+
184
+ return callback(null, cert)
185
+ }
package/package.json ADDED
@@ -0,0 +1,172 @@
1
+ {
2
+ "name": "solid-server",
3
+ "description": "Solid server on top of the file-system",
4
+ "version": "5.6.9-beta",
5
+ "author": {
6
+ "name": "Tim Berners-Lee",
7
+ "email": "timbl@w3.org"
8
+ },
9
+ "contributors": [
10
+ {
11
+ "name": "Jackson Morgan",
12
+ "email": "jacksonm@inrupt.com"
13
+ },
14
+ {
15
+ "name": "Nicola Greco",
16
+ "email": "me@nicolagreco.com"
17
+ },
18
+ {
19
+ "name": "Kjetil Kjernsmo",
20
+ "email": "kjetil@inrupt.com",
21
+ "url": "http://kjetil.kjernsmo.net/"
22
+ },
23
+ {
24
+ "name": "Martin Martinez Rivera",
25
+ "email": "martinmr@mit.edu"
26
+ },
27
+ {
28
+ "name": "Andrei Sambra",
29
+ "url": "https://deiu.me/"
30
+ },
31
+ {
32
+ "name": "Ruben Taelman",
33
+ "url": "https://www.rubensworks.net/"
34
+ },
35
+ {
36
+ "name": "Ruben Verborgh",
37
+ "email": "ruben@verborgh.org",
38
+ "url": "https://ruben.verborgh.org/"
39
+ },
40
+ {
41
+ "name": "Dmitri Zagidulin",
42
+ "url": "https://github.com/dmitrizagidulin/"
43
+ },
44
+ {
45
+ "name": "Arne Hassel",
46
+ "email": "arne.hassel@inrupt.com",
47
+ "url": "https://icanhasweb.net/"
48
+ }
49
+ ],
50
+ "license": "MIT",
51
+ "repository": {
52
+ "type": "git",
53
+ "url": "https://github.com/solid/node-solid-server"
54
+ },
55
+ "homepage": "https://github.com/solid/node-solid-server",
56
+ "bugs": "https://github.com/solid/node-solid-server/issues",
57
+ "dependencies": {
58
+ "@solid/acl-check": "^0.4.5",
59
+ "@solid/oidc-auth-manager": "^0.24.1",
60
+ "@solid/oidc-op": "0.11.5",
61
+ "async-lock": "^1.3.0",
62
+ "body-parser": "^1.19.0",
63
+ "bootstrap": "^3.4.1",
64
+ "busboy": "^0.3.1",
65
+ "cached-path-relative": "^1.0.2",
66
+ "camelize": "^1.0.0",
67
+ "cheerio": "^1.0.0-rc.10",
68
+ "colorette": "^1.2.2",
69
+ "commander": "^7.2.0",
70
+ "cors": "^2.8.5",
71
+ "debug": "^4.3.2",
72
+ "express": "^4.17.1",
73
+ "express-handlebars": "^5.3.2",
74
+ "express-session": "^1.17.2",
75
+ "extend": "^3.0.2",
76
+ "from2": "^2.3.0",
77
+ "fs-extra": "^10.0.0",
78
+ "get-folder-size": "^2.0.1",
79
+ "glob": "^7.1.7",
80
+ "global-tunnel-ng": "^2.7.1",
81
+ "handlebars": "^4.7.7",
82
+ "http-proxy-middleware": "^2.0.1",
83
+ "inquirer": "^8.1.2",
84
+ "into-stream": "^6.0.0",
85
+ "ip-range-check": "0.2.0",
86
+ "is-ip": "^3.1.0",
87
+ "li": "^1.3.0",
88
+ "mashlib": "1.7.5-beta",
89
+ "mime-types": "^2.1.31",
90
+ "negotiator": "^0.6.2",
91
+ "node-fetch": "^2.6.1",
92
+ "node-forge": "^0.10.0",
93
+ "nodemailer": "^6.6.3",
94
+ "oidc-op-express": "^0.0.3",
95
+ "owasp-password-strength-test": "^1.3.0",
96
+ "rdflib": "^2.2.7",
97
+ "recursive-readdir": "^2.2.2",
98
+ "request": "^2.88.2",
99
+ "rimraf": "^3.0.2",
100
+ "solid-namespace": "^0.5.1",
101
+ "solid-ws": "^0.4.3",
102
+ "text-encoder-lite": "^2.0.0",
103
+ "the-big-username-blacklist": "^1.5.2",
104
+ "ulid": "^2.3.0",
105
+ "urijs": "^1.19.7",
106
+ "uuid": "^8.3.2",
107
+ "valid-url": "^1.0.9",
108
+ "validator": "^13.6.0",
109
+ "vhost": "^3.0.2"
110
+ },
111
+ "devDependencies": {
112
+ "@solid/solid-auth-oidc": "^0.3.0",
113
+ "chai": "4.3.4",
114
+ "chai-as-promised": "7.1.1",
115
+ "cross-env": "7.0.3",
116
+ "dirty-chai": "2.0.1",
117
+ "localstorage-memory": "1.0.3",
118
+ "mocha": "9.0.2",
119
+ "nock": "13.1.1",
120
+ "node-mocks-http": "1.10.1",
121
+ "nyc": "15.1.0",
122
+ "pre-commit": "1.2.2",
123
+ "randombytes": "2.1.0",
124
+ "sinon": "11.1.1",
125
+ "sinon-chai": "3.7.0",
126
+ "snyk": "1.663.0",
127
+ "standard": "16.0.3",
128
+ "supertest": "6.1.3",
129
+ "turtle-validator": "1.1.1",
130
+ "whatwg-url": "8.7.0"
131
+ },
132
+ "pre-commit": [
133
+ "standard"
134
+ ],
135
+ "main": "index.js",
136
+ "scripts": {
137
+ "build": "echo nothing to build",
138
+ "solid": "node ./bin/solid",
139
+ "standard": "standard '{bin,examples,lib,test}/**/*.js'",
140
+ "validate": "node ./test/validate-turtle.js",
141
+ "nyc": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 nyc --reporter=text-summary mocha --recursive test/integration/ test/unit/",
142
+ "mocha": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 mocha --recursive test/integration/ test/unit/",
143
+ "prepublishOnly": "npm test",
144
+ "postpublish": "git push --follow-tags",
145
+ "test": "npm run standard && npm run validate && npm run nyc",
146
+ "clean": "rimraf config/templates config/views",
147
+ "reset": "rimraf .db data && npm run clean"
148
+ },
149
+ "nyc": {
150
+ "reporter": [
151
+ "html",
152
+ "text-summary"
153
+ ],
154
+ "cache": true
155
+ },
156
+ "standard": {
157
+ "globals": [
158
+ "after",
159
+ "afterEach",
160
+ "before",
161
+ "beforeEach",
162
+ "describe",
163
+ "it"
164
+ ]
165
+ },
166
+ "bin": {
167
+ "solid": "bin/solid"
168
+ },
169
+ "engines": {
170
+ "node": ">=12.0"
171
+ }
172
+ }
package/renovate.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": [
3
+ "config:base"
4
+ ]
5
+ }
package/robots.txt ADDED
@@ -0,0 +1,3 @@
1
+ User-agent: *
2
+ # Allow all crawling (subject to ACLs as usual, of course)
3
+ Disallow:
package/robots.txt.acl ADDED
@@ -0,0 +1,15 @@
1
+ # ACL for the default robots.txt resource
2
+ # Server operators will be able to override it as they wish
3
+ # Public-readable
4
+
5
+ @prefix acl: <http://www.w3.org/ns/auth/acl#>.
6
+ @prefix foaf: <http://xmlns.com/foaf/0.1/>.
7
+
8
+ <#public>
9
+ a acl:Authorization;
10
+
11
+ acl:agentClass foaf:Agent; # everyone
12
+
13
+ acl:accessTo </robots.txt>;
14
+
15
+ acl:mode acl:Read.
@@ -0,0 +1,78 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Admin Signup</title>
5
+ <link href="data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAAF0lEQVRIx2NgGAWjYBSMglEwCkbBSAcACBAAAeaR9cIAAAAASUVORK5CYII=" rel="favicon" type="image/x-icon" />
6
+ <style>
7
+ body {
8
+ font-family: sans-serif;
9
+ }
10
+ input {
11
+ width: 200px;
12
+ line-height: 1.5em;
13
+ padding: 5px;
14
+ font-size: 1.2em;
15
+ border-radius: 4px;
16
+ border: 1px solid #ddd;
17
+ margin-bottom: 10px;
18
+ }
19
+
20
+ button {
21
+ display: inline-block;
22
+ padding: 25px;
23
+ background: #69f;
24
+ border-radius: 4px;
25
+ font-weight: normal;
26
+ font-size: 14px;
27
+ color: #fff;
28
+ letter-spacing: 1px;
29
+ line-height: 1px;
30
+ text-transform: uppercase;
31
+ border: 0;
32
+ min-width: 200px;
33
+ cursor: pointer;
34
+ }
35
+ </style>
36
+
37
+ </head>
38
+ <body>
39
+
40
+ <div id="accounts">
41
+ <h2>Recover your account</h2>
42
+ <input id="account" type="account" placeholder="Enter your account address">
43
+ <br>
44
+ <button onclick='retrieveAccount()'>Retrieve account</button>
45
+ </div>
46
+
47
+ <script type="text/javascript">
48
+ function retrieveAccount () {
49
+ var account = document.getElementById('account').value
50
+ var url = '/recovery/request'
51
+ var data = 'webid=' + account
52
+
53
+ var http = new XMLHttpRequest()
54
+ http.open('POST', url)
55
+ http.withCredentials = true
56
+ http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
57
+ http.onreadystatechange = function () {
58
+ if (this.readyState === this.DONE) {
59
+ if (this.status !== 200) {
60
+ return err(new Error('Request failed'))
61
+ }
62
+
63
+ alert('An email should arrive to you in minutes')
64
+ }
65
+ }
66
+ http.send(data)
67
+ }
68
+
69
+ function err (err) {
70
+ console.log('called done')
71
+ if (err) {
72
+ console.log(err)
73
+ }
74
+ }
75
+
76
+ </script>
77
+ </body>
78
+ </html>
@@ -0,0 +1 @@
1
+ <script>location.replace(`/common/popup.html${location.hash}`)</script>
@@ -0,0 +1,108 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Admin Signup</title>
5
+ <link href="data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAAF0lEQVRIx2NgGAWjYBSMglEwCkbBSAcACBAAAeaR9cIAAAAASUVORK5CYII=" rel="favicon" type="image/x-icon" />
6
+ <style>
7
+ body {
8
+ font-family: sans-serif;
9
+ }
10
+ input {
11
+ width: 200px;
12
+ line-height: 1.5em;
13
+ padding: 5px;
14
+ font-size: 1.2em;
15
+ border-radius: 4px;
16
+ border: 1px solid #ddd;
17
+ margin-bottom: 10px;
18
+ }
19
+
20
+ button {
21
+ display: inline-block;
22
+ padding: 25px;
23
+ background: #69f;
24
+ border-radius: 4px;
25
+ font-weight: normal;
26
+ font-size: 14px;
27
+ color: #fff;
28
+ letter-spacing: 1px;
29
+ line-height: 1px;
30
+ text-transform: uppercase;
31
+ border: 0;
32
+ min-width: 200px;
33
+ cursor: pointer;
34
+ }
35
+ </style>
36
+
37
+ </head>
38
+ <body>
39
+
40
+
41
+ <div id="accounts">
42
+ <h2>Create your account</h2>
43
+ <input id="email" type="email" placeholder="Email (recovery)">
44
+ <br>
45
+ <button onclick='createAccount()'>Create account</button>
46
+ </div>
47
+
48
+ <form id="cert" method="POST" action='/api/accounts/cert' target="spkacResult" style="display: none">
49
+ <h2>Finish by issuing credentials in the form of a certificate</h2>
50
+ <keygen name="spkac" keytype="rsa" hidden />
51
+ <iframe id="spkacResult" name="spkacResult" sandbox="allow-same-origin allow-forms" hidden></iframe>
52
+ <input type="hidden" id="webid" name="webid" value="">
53
+ <p>Your WebID is: <span id="your-webid"></span></p>
54
+ <br>
55
+ <input type="text" id="name" name="name" placeholder="Certificate label"> (e.g. your name and device)
56
+ <br>
57
+ <button onclick="done()" type="submit">Issue credentials</button>
58
+ </form>
59
+
60
+ <script type="text/javascript">
61
+ function createAccount () {
62
+ var email = document.getElementById('email').value
63
+ var url = '/api/accounts/new'
64
+ var data = 'email=' + email
65
+
66
+ var http = new XMLHttpRequest()
67
+ http.open('POST', url)
68
+ http.withCredentials = true
69
+ http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
70
+ http.onreadystatechange = function () {
71
+ if (this.readyState === this.DONE) {
72
+ if (this.status !== 200) {
73
+ return err(new Error('Request failed'))
74
+ }
75
+ var webid = this.getResponseHeader('User')
76
+ if (!webid || webid.length === 0) {
77
+ return err(new Error('WebID is not set in User'))
78
+ }
79
+ // Account is created
80
+ document.getElementById('webid').value = webid
81
+ document.getElementById('your-webid').innerHTML = webid
82
+ document.getElementById('accounts').style.display = 'none'
83
+ document.getElementById('cert').style.display = ''
84
+ }
85
+ }
86
+ http.send(data)
87
+ }
88
+
89
+ function err (err) {
90
+ console.log('called done')
91
+ if (err) {
92
+ console.log(err)
93
+ }
94
+ }
95
+
96
+ function done () {
97
+ document.getElementById('cert').style.display = 'none'
98
+ var done = document.createElement('div')
99
+ done.innerHTML = '<h2>You\'re all set!</h2>'
100
+ done.innerHTML += '<p>as soon as you will reset the page, you will be logged in!</p>'
101
+ document.querySelector('body').appendChild(done)
102
+ }
103
+
104
+ document.querySelector('keygen').setAttribute('challenge', Date.now())
105
+
106
+ </script>
107
+ </body>
108
+ </html>
@@ -0,0 +1,14 @@
1
+ # ACL resource for the static resources
2
+
3
+ @prefix acl: <http://www.w3.org/ns/auth/acl#>.
4
+ @prefix foaf: <http://xmlns.com/foaf/0.1/>.
5
+
6
+ # Public-readable
7
+ <#public>
8
+ a acl:Authorization;
9
+
10
+ acl:agentClass foaf:Agent; # everyone
11
+
12
+ acl:accessTo <./signup.html>;
13
+
14
+ acl:mode acl:Read.