wiki-server 0.24.0 → 0.24.2
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/lib/page.coffee +5 -6
- package/lib/search.coffee +29 -11
- package/lib/server.coffee +12 -5
- package/lib/sitemap.coffee +4 -7
- package/package.json +11 -12
package/lib/page.coffee
CHANGED
|
@@ -15,7 +15,6 @@ path = require 'path'
|
|
|
15
15
|
events = require 'events'
|
|
16
16
|
glob = require 'glob'
|
|
17
17
|
|
|
18
|
-
mkdirp = require 'mkdirp'
|
|
19
18
|
async = require 'async'
|
|
20
19
|
|
|
21
20
|
random_id = require './random_id'
|
|
@@ -31,7 +30,7 @@ module.exports = exports = (argv) ->
|
|
|
31
30
|
|
|
32
31
|
wikiName = new URL(argv.url).hostname
|
|
33
32
|
|
|
34
|
-
|
|
33
|
+
fs.mkdir argv.db, { recursive: true }, (e) ->
|
|
35
34
|
if e then throw e
|
|
36
35
|
|
|
37
36
|
#### Private utility methods. ####
|
|
@@ -53,7 +52,7 @@ module.exports = exports = (argv) ->
|
|
|
53
52
|
console.log "ERROR: problem page #{loc} moved to recycler"
|
|
54
53
|
)
|
|
55
54
|
else
|
|
56
|
-
|
|
55
|
+
fs.mkdir(path.dirname(recyclePage), { recursive: true }, (err) ->
|
|
57
56
|
if err
|
|
58
57
|
console.log "ERROR: creating recycler", err
|
|
59
58
|
else
|
|
@@ -134,7 +133,7 @@ module.exports = exports = (argv) ->
|
|
|
134
133
|
cb(err)
|
|
135
134
|
)
|
|
136
135
|
else
|
|
137
|
-
|
|
136
|
+
fs.mkdir(path.dirname(recycleLoc), { recursive: true }, (err) ->
|
|
138
137
|
if err then cb(err)
|
|
139
138
|
fs.rename(loc, recycleLoc, (err) ->
|
|
140
139
|
cb(err)
|
|
@@ -179,7 +178,7 @@ module.exports = exports = (argv) ->
|
|
|
179
178
|
cb(err)
|
|
180
179
|
)
|
|
181
180
|
else
|
|
182
|
-
|
|
181
|
+
fs.mkdir(path.dirname(recycleLoc), { recursive: true }, (err) ->
|
|
183
182
|
if err then cb(err)
|
|
184
183
|
copyFile(loc, recycleLoc, (err) ->
|
|
185
184
|
cb(err)
|
|
@@ -234,7 +233,7 @@ module.exports = exports = (argv) ->
|
|
|
234
233
|
cb(err)
|
|
235
234
|
)
|
|
236
235
|
else
|
|
237
|
-
|
|
236
|
+
fs.mkdir(path.dirname(loc), { recursive: true }, (err) ->
|
|
238
237
|
if err then cb(err)
|
|
239
238
|
fs.writeFile(loc, page, (err) ->
|
|
240
239
|
if err
|
package/lib/search.coffee
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
fs = require 'fs'
|
|
12
12
|
path = require 'path'
|
|
13
13
|
events = require 'events'
|
|
14
|
+
url = require 'node:url'
|
|
14
15
|
writeFileAtomic = require 'write-file-atomic'
|
|
15
|
-
mkdirp = require 'mkdirp'
|
|
16
16
|
|
|
17
17
|
miniSearch = require 'minisearch'
|
|
18
18
|
|
|
@@ -84,7 +84,7 @@ module.exports = exports = (argv) ->
|
|
|
84
84
|
touch indexUpdateFlag, (err) ->
|
|
85
85
|
cb()
|
|
86
86
|
else
|
|
87
|
-
|
|
87
|
+
fs.mkdir argv.status, { recursive: true }, ->
|
|
88
88
|
writeFileAtomic siteIndexLoc, JSON.stringify(siteIndex), (e) ->
|
|
89
89
|
return cb(e) if e
|
|
90
90
|
touch indexUpdateFlag, (err) ->
|
|
@@ -131,21 +131,39 @@ module.exports = exports = (argv) ->
|
|
|
131
131
|
console.log "SITE INDEX *** save failed: " + e if e
|
|
132
132
|
itself.stop()
|
|
133
133
|
|
|
134
|
+
extractItemText = (text) ->
|
|
135
|
+
return text.replace(/\[([^\]]*?)\][\[\(].*?[\]\)]/g, " $1 ")
|
|
136
|
+
.replace(/\[{2}|\[(?:[\S]+)|\]{1,2}/g, ' ')
|
|
137
|
+
.replace(/\n/g, ' ')
|
|
138
|
+
.replace(/<style.*?<\/style>/g, ' ')
|
|
139
|
+
.replace(/<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g, ' ')
|
|
140
|
+
.replace(/<(?:[^>])+>/g, ' ')
|
|
141
|
+
.replace(/(https?.*?)(?=\p{White_Space}|\p{Quotation_Mark}|$)/gu, (match) ->
|
|
142
|
+
myUrl = url.parse(match)
|
|
143
|
+
return myUrl.hostname + myUrl.pathname)
|
|
144
|
+
.replace(/[\p{P}\p{Emoji}\p{Symbol}}]+/gu, ' ')
|
|
145
|
+
.replace /[\p{White_Space}\n\t]+/gu, ' '
|
|
146
|
+
|
|
147
|
+
|
|
134
148
|
extractPageText = (pageText, currentItem, currentIndex, array) ->
|
|
135
149
|
# console.log('extractPageText', pageText, currentItem, currentIndex, array)
|
|
136
150
|
try
|
|
137
151
|
if currentItem.text?
|
|
138
152
|
switch currentItem.type
|
|
139
|
-
when 'paragraph', 'markdown', 'html', 'reference'
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
pageText +=
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
153
|
+
when 'paragraph', 'markdown', 'html', 'reference', 'image', 'pagefold', 'math', 'mathjax', 'code'
|
|
154
|
+
pageText += extractItemText currentItem.text
|
|
155
|
+
when 'audio', 'video', 'frame'
|
|
156
|
+
pageText += extractItemText(currentItem.text.split(/\r\n?|\n/)
|
|
157
|
+
.map((line) ->
|
|
158
|
+
firstWord = line.split(/\p{White_Space}/u)[0]
|
|
159
|
+
if firstWord.startsWith('http') or firstWord.toUpperCase() is firstWord or firstWord.startsWith('//')
|
|
160
|
+
# line is markup
|
|
161
|
+
return ''
|
|
162
|
+
else
|
|
163
|
+
return line
|
|
164
|
+
).join(' '))
|
|
147
165
|
catch err
|
|
148
|
-
throw new Error("Error extracting text from #{currentIndex}, #{err}, #{err.stack}")
|
|
166
|
+
throw new Error("Error extracting text from #{currentIndex}, #{JSON.stringify(currentItem)} #{err}, #{err.stack}")
|
|
149
167
|
pageText
|
|
150
168
|
|
|
151
169
|
|
package/lib/server.coffee
CHANGED
|
@@ -26,13 +26,17 @@ url = require 'url'
|
|
|
26
26
|
{ pipeline } = require 'node:stream/promises'
|
|
27
27
|
|
|
28
28
|
# From npm
|
|
29
|
-
mkdirp = require 'mkdirp'
|
|
30
29
|
express = require 'express'
|
|
31
30
|
hbs = require 'express-hbs'
|
|
32
31
|
glob = require 'glob'
|
|
33
32
|
async = require 'async'
|
|
34
33
|
f = require('flates')
|
|
35
|
-
|
|
34
|
+
|
|
35
|
+
createDOMPurify = require('dompurify')
|
|
36
|
+
{ JSDOM } = require('jsdom')
|
|
37
|
+
|
|
38
|
+
window = new JSDOM('').window
|
|
39
|
+
DOMPurify = createDOMPurify(window)
|
|
36
40
|
|
|
37
41
|
# node-fetch is now ESM only
|
|
38
42
|
fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
|
|
@@ -73,7 +77,7 @@ render = (page) ->
|
|
|
73
77
|
f.p(resolveClient.resolveLinks(story.text or story.caption or 'uploaded image'))
|
|
74
78
|
else if story.type is 'html'
|
|
75
79
|
f.div {class: "item html"},
|
|
76
|
-
f.p(resolveClient.resolveLinks(story.text or '', sanitize))
|
|
80
|
+
f.p(resolveClient.resolveLinks(story.text or '', DOMPurify.sanitize))
|
|
77
81
|
else f.div {class: "item"}, f.p(resolveClient.resolveLinks(story.text or ''))
|
|
78
82
|
).join('\n')
|
|
79
83
|
|
|
@@ -184,7 +188,10 @@ module.exports = exports = (argv) ->
|
|
|
184
188
|
|
|
185
189
|
# use logger, at least in development, probably needs a param to configure (or turn off).
|
|
186
190
|
# use stream to direct to somewhere other than stdout.
|
|
187
|
-
|
|
191
|
+
wikiName = new URL(argv.url).hostname
|
|
192
|
+
logger.token('vhost', () ->
|
|
193
|
+
return wikiName)
|
|
194
|
+
app.use(logger(':vhost :method :url :status :res[content-length] - :response-time ms'))
|
|
188
195
|
app.use(cookieParser())
|
|
189
196
|
app.use(bodyParser.json({ limit: argv.uploadLimit}))
|
|
190
197
|
app.use(bodyParser.urlencoded({ extended: true, limit: argv.uploadLimit}))
|
|
@@ -427,7 +434,7 @@ module.exports = exports = (argv) ->
|
|
|
427
434
|
res.send('Favicon Saved')
|
|
428
435
|
|
|
429
436
|
else
|
|
430
|
-
|
|
437
|
+
fs.mkdir argv.status, { recursive: true }, ->
|
|
431
438
|
fs.writeFile favLoc, buf, (e) ->
|
|
432
439
|
if e then return res.e e
|
|
433
440
|
res.send('Favicon Saved')
|
package/lib/sitemap.coffee
CHANGED
|
@@ -12,11 +12,8 @@ fs = require 'fs'
|
|
|
12
12
|
path = require 'path'
|
|
13
13
|
events = require 'events'
|
|
14
14
|
writeFileAtomic = require 'write-file-atomic'
|
|
15
|
-
_ = require 'lodash'
|
|
16
15
|
xml2js = require 'xml2js'
|
|
17
16
|
|
|
18
|
-
mkdirp = require 'mkdirp'
|
|
19
|
-
|
|
20
17
|
synopsis = require 'wiki-client/lib/synopsis'
|
|
21
18
|
|
|
22
19
|
asSlug = (name) ->
|
|
@@ -100,7 +97,7 @@ module.exports = exports = (argv) ->
|
|
|
100
97
|
idx = slugs.indexOf(file)
|
|
101
98
|
|
|
102
99
|
if ~idx
|
|
103
|
-
|
|
100
|
+
sitemap.splice(idx,1)
|
|
104
101
|
|
|
105
102
|
cb()
|
|
106
103
|
|
|
@@ -111,7 +108,7 @@ module.exports = exports = (argv) ->
|
|
|
111
108
|
return cb(e) if e
|
|
112
109
|
cb()
|
|
113
110
|
else
|
|
114
|
-
|
|
111
|
+
fs.mkdir argv.status, { recursive: true }, ->
|
|
115
112
|
writeFileAtomic sitemapLoc, JSON.stringify(sitemap), (e) ->
|
|
116
113
|
return cb(e) if e
|
|
117
114
|
cb()
|
|
@@ -134,7 +131,7 @@ module.exports = exports = (argv) ->
|
|
|
134
131
|
|
|
135
132
|
xmlSitemapSave = (sitemap, cb) ->
|
|
136
133
|
xmlmap = []
|
|
137
|
-
|
|
134
|
+
sitemap.forEach (page) ->
|
|
138
135
|
result = {}
|
|
139
136
|
result["loc"] = argv.url + "/" + page.slug + ".html"
|
|
140
137
|
if page.date?
|
|
@@ -151,7 +148,7 @@ module.exports = exports = (argv) ->
|
|
|
151
148
|
return cb(e) if e
|
|
152
149
|
cb()
|
|
153
150
|
else
|
|
154
|
-
|
|
151
|
+
fs.mkdir argv.status, { recursive: true }, ->
|
|
155
152
|
writeFileAtomic xmlSitemapLoc, xml, (e) ->
|
|
156
153
|
return cb(e) if e
|
|
157
154
|
cb()
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wiki-server",
|
|
3
3
|
"description": "A Federated Wiki Server",
|
|
4
|
-
"version": "0.24.
|
|
4
|
+
"version": "0.24.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Ward Cunningham",
|
|
7
7
|
"email": "ward@c2.com",
|
|
@@ -20,40 +20,39 @@
|
|
|
20
20
|
}
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@mapbox/sanitize-caja": "^0.1.4",
|
|
24
23
|
"async": "^3.2.4",
|
|
25
24
|
"body-parser": "^1.20.2",
|
|
26
25
|
"client-sessions": "^0.8.0",
|
|
27
26
|
"coffeescript": "^2.5.0",
|
|
28
27
|
"cookie-parser": "^1.4.4",
|
|
28
|
+
"dompurify": "^3.1.0",
|
|
29
29
|
"errorhandler": "^1.5.1",
|
|
30
30
|
"express": "^4.17.1",
|
|
31
31
|
"express-hbs": "^2.5.0",
|
|
32
32
|
"flates": "0.0.5",
|
|
33
33
|
"glob": "^7.2.3",
|
|
34
|
-
"
|
|
34
|
+
"jsdom": "^24.0.0",
|
|
35
35
|
"method-override": "^3.0.0",
|
|
36
|
-
"minisearch": "^6.0
|
|
37
|
-
"mkdirp": "^0.5.6",
|
|
36
|
+
"minisearch": "^6.3.0",
|
|
38
37
|
"morgan": "^1.9.1",
|
|
39
38
|
"node-fetch": "^3.3.2",
|
|
40
39
|
"write-file-atomic": "^5.0.0",
|
|
41
|
-
"xml2js": "^0.
|
|
40
|
+
"xml2js": "^0.6.2"
|
|
42
41
|
},
|
|
43
42
|
"scripts": {
|
|
44
43
|
"test": "grunt mochaTest"
|
|
45
44
|
},
|
|
46
45
|
"devDependencies": {
|
|
47
46
|
"grunt": "^1.6.1",
|
|
48
|
-
"grunt-contrib-watch": "^1.
|
|
47
|
+
"grunt-contrib-watch": "^1.1.0",
|
|
49
48
|
"grunt-git-authors": "^3.2.0",
|
|
50
|
-
"grunt-mocha-test": "^0.13.
|
|
51
|
-
"mocha": "^10.
|
|
49
|
+
"grunt-mocha-test": "^0.13.3",
|
|
50
|
+
"mocha": "^10.4.0",
|
|
52
51
|
"should": "^13.2.3",
|
|
53
|
-
"supertest": "^6.3.
|
|
54
|
-
"wiki-client": "^0.29.
|
|
52
|
+
"supertest": "^6.3.4",
|
|
53
|
+
"wiki-client": "^0.29.1",
|
|
55
54
|
"wiki-plugin-activity": "^0.5.0",
|
|
56
|
-
"wiki-plugin-video": "^0.3.
|
|
55
|
+
"wiki-plugin-video": "^0.3.1"
|
|
57
56
|
},
|
|
58
57
|
"engines": {
|
|
59
58
|
"node": ">=18.x"
|