forked from nodeSolidServer/node-solid-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsolid-host.js
More file actions
163 lines (148 loc) · 4.29 KB
/
solid-host.js
File metadata and controls
163 lines (148 loc) · 4.29 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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
'use strict'
const url = require('url')
const defaults = require('../../config/defaults')
/**
* Represents the URI that a Solid server is installed on, and manages user
* account URI creation.
*
* @class SolidHost
*/
class SolidHost {
/**
* @constructor
* @param [options={}]
* @param [options.port] {number}
* @param [options.serverUri] {string} Fully qualified URI that this Solid
* server is listening on, e.g. `https://databox.me`
* @param [options.live] {boolean} Whether turn on WebSockets / LDP live
* @param [options.root] {string} Path to root data directory
* @param [options.multiuser] {boolean} Multiuser (account creation) mode
*/
constructor (options = {}) {
this.port = options.port || defaults.port
this.serverUri = options.serverUri || defaults.serverUri
this.parsedUri = url.parse(this.serverUri)
this.host = this.parsedUri.host
this.hostname = this.parsedUri.hostname
this.live = options.live
this.root = options.root
this.multiuser = options.multiuser
this.webid = options.webid
}
/**
* Factory method, returns an instance of `SolidHost`.
*
* @param [options={}] {Object} See `constructor()` docstring.
*
* @return {SolidHost}
*/
static from (options = {}) {
return new SolidHost(options)
}
/**
* Composes and returns an account URI for a given username, in multi-user mode.
* Usage:
*
* ```
* // host.serverUri === 'https://example.com'
*
* host.accountUriFor('alice') // -> 'https://alice.example.com'
* ```
*
* @param accountName {string}
*
* @throws {TypeError} If no accountName given, or if serverUri not initialized
* @return {string}
*/
accountUriFor (accountName) {
if (!accountName) {
throw TypeError('Cannot construct uri for blank account name')
}
if (!this.parsedUri) {
throw TypeError('Cannot construct account, host not initialized with serverUri')
}
return this.parsedUri.protocol + '//' + accountName + '.' + this.host
}
/**
* Determines whether the given user is allowed to restore a session
* from the given origin.
*
* @param userId {?string}
* @param origin {?string}
* @return {boolean}
*/
allowsSessionFor (userId, origin) {
// Allow no user or an empty origin
if (!userId || !origin) return true
// Allow the server and subdomains
const originHost = getHostName(origin)
const serverHost = getHostName(this.serverUri)
if (originHost === serverHost) return true
if (originHost.endsWith('.' + serverHost)) return true
// Allow the user's own domain
const userHost = getHostName(userId)
if (originHost === userHost) return true
return false
}
/**
* Returns the /authorize endpoint URL object (used in login requests, etc).
*
* @return {URL}
*/
get authEndpoint () {
let authUrl = url.resolve(this.serverUri, '/authorize')
return url.parse(authUrl)
}
/**
* Returns a cookie domain, based on the current host's serverUri.
*
* @return {string|null}
*/
get cookieDomain () {
let cookieDomain = null
if (this.hostname.split('.').length > 1) {
// For single-level domains like 'localhost', do not set the cookie domain
// See section on 'domain' attribute at https://curl.haxx.se/rfc/cookie_spec.html
cookieDomain = '.' + this.hostname
}
return cookieDomain
}
/**
* Returns the protocol for an incoming request ('http' or 'https')
* @returns {string}
*/
protocol (req) {
// Obtain the protocol from the configured server URI
// (in case the server is running behind a reverse proxy)
const protocol = this.serverUri.replace(/:.*/, '')
return protocol || req.protocol
}
/**
* Taken from utils.getBaseUri()
*
* @param req {IncomingRequest}
*
* @returns {string}
*/
getBaseUri (req) {
return this.protocol(req) + '://' + req.get('host')
}
/**
* @param req {IncomingRequest}
*
* @returns {string}
*/
parseTargetUrl (req) {
return url.format({
protocol: this.protocol(req),
host: req.get('host'),
pathname: url.resolve(req.baseUrl, req.path),
query: req.query
})
}
}
function getHostName (url) {
const match = url.match(/^\w+:\/*([^/]+)/)
return match ? match[1] : ''
}
module.exports = SolidHost