added more to publisher
This commit is contained in:
		
							parent
							
								
									f649ccf3d0
								
							
						
					
					
						commit
						41718caa46
					
				
							
								
								
									
										129
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										129
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -260,6 +260,11 @@ | ||||
|         "picomatch": "^2.0.4" | ||||
|       } | ||||
|     }, | ||||
|     "append-field": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", | ||||
|       "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" | ||||
|     }, | ||||
|     "aproba": { | ||||
|       "version": "1.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", | ||||
| @ -480,6 +485,16 @@ | ||||
|       "dev": true, | ||||
|       "optional": true | ||||
|     }, | ||||
|     "bindings": { | ||||
|       "version": "1.5.0", | ||||
|       "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", | ||||
|       "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", | ||||
|       "dev": true, | ||||
|       "optional": true, | ||||
|       "requires": { | ||||
|         "file-uri-to-path": "1.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "bl": { | ||||
|       "version": "2.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz", | ||||
| @ -688,8 +703,7 @@ | ||||
|     "buffer-from": { | ||||
|       "version": "1.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", | ||||
|       "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", | ||||
|       "dev": true | ||||
|       "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" | ||||
|     }, | ||||
|     "buffer-xor": { | ||||
|       "version": "1.0.3", | ||||
| @ -703,6 +717,38 @@ | ||||
|       "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "busboy": { | ||||
|       "version": "0.2.14", | ||||
|       "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", | ||||
|       "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", | ||||
|       "requires": { | ||||
|         "dicer": "0.2.5", | ||||
|         "readable-stream": "1.1.x" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "isarray": { | ||||
|           "version": "0.0.1", | ||||
|           "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", | ||||
|           "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" | ||||
|         }, | ||||
|         "readable-stream": { | ||||
|           "version": "1.1.14", | ||||
|           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", | ||||
|           "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", | ||||
|           "requires": { | ||||
|             "core-util-is": "~1.0.0", | ||||
|             "inherits": "~2.0.1", | ||||
|             "isarray": "0.0.1", | ||||
|             "string_decoder": "~0.10.x" | ||||
|           } | ||||
|         }, | ||||
|         "string_decoder": { | ||||
|           "version": "0.10.31", | ||||
|           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", | ||||
|           "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "bytes": { | ||||
|       "version": "3.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", | ||||
| @ -969,7 +1015,6 @@ | ||||
|       "version": "1.6.2", | ||||
|       "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", | ||||
|       "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "buffer-from": "^1.0.0", | ||||
|         "inherits": "^2.0.3", | ||||
| @ -1238,6 +1283,38 @@ | ||||
|       "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", | ||||
|       "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" | ||||
|     }, | ||||
|     "dicer": { | ||||
|       "version": "0.2.5", | ||||
|       "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", | ||||
|       "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", | ||||
|       "requires": { | ||||
|         "readable-stream": "1.1.x", | ||||
|         "streamsearch": "0.1.2" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "isarray": { | ||||
|           "version": "0.0.1", | ||||
|           "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", | ||||
|           "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" | ||||
|         }, | ||||
|         "readable-stream": { | ||||
|           "version": "1.1.14", | ||||
|           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", | ||||
|           "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", | ||||
|           "requires": { | ||||
|             "core-util-is": "~1.0.0", | ||||
|             "inherits": "~2.0.1", | ||||
|             "isarray": "0.0.1", | ||||
|             "string_decoder": "~0.10.x" | ||||
|           } | ||||
|         }, | ||||
|         "string_decoder": { | ||||
|           "version": "0.10.31", | ||||
|           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", | ||||
|           "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "diffie-hellman": { | ||||
|       "version": "5.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", | ||||
| @ -1659,6 +1736,13 @@ | ||||
|       "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "file-uri-to-path": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", | ||||
|       "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", | ||||
|       "dev": true, | ||||
|       "optional": true | ||||
|     }, | ||||
|     "fill-range": { | ||||
|       "version": "4.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", | ||||
| @ -2708,6 +2792,28 @@ | ||||
|       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", | ||||
|       "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" | ||||
|     }, | ||||
|     "multer": { | ||||
|       "version": "1.4.2", | ||||
|       "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.2.tgz", | ||||
|       "integrity": "sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==", | ||||
|       "requires": { | ||||
|         "append-field": "^1.0.0", | ||||
|         "busboy": "^0.2.11", | ||||
|         "concat-stream": "^1.5.2", | ||||
|         "mkdirp": "^0.5.1", | ||||
|         "object-assign": "^4.1.1", | ||||
|         "on-finished": "^2.3.0", | ||||
|         "type-is": "^1.6.4", | ||||
|         "xtend": "^4.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "nan": { | ||||
|       "version": "2.14.1", | ||||
|       "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", | ||||
|       "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", | ||||
|       "dev": true, | ||||
|       "optional": true | ||||
|     }, | ||||
|     "nanomatch": { | ||||
|       "version": "1.2.13", | ||||
|       "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", | ||||
| @ -4072,6 +4178,11 @@ | ||||
|       "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "streamsearch": { | ||||
|       "version": "0.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", | ||||
|       "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" | ||||
|     }, | ||||
|     "string-hash": { | ||||
|       "version": "1.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz", | ||||
| @ -4349,8 +4460,7 @@ | ||||
|     "typedarray": { | ||||
|       "version": "0.0.6", | ||||
|       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", | ||||
|       "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", | ||||
|       "dev": true | ||||
|       "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" | ||||
|     }, | ||||
|     "typescript": { | ||||
|       "version": "3.9.5", | ||||
| @ -4632,7 +4742,11 @@ | ||||
|           "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", | ||||
|           "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", | ||||
|           "dev": true, | ||||
|           "optional": true | ||||
|           "optional": true, | ||||
|           "requires": { | ||||
|             "bindings": "^1.5.0", | ||||
|             "nan": "^2.12.1" | ||||
|           } | ||||
|         }, | ||||
|         "glob-parent": { | ||||
|           "version": "3.1.0", | ||||
| @ -4766,8 +4880,7 @@ | ||||
|     "xtend": { | ||||
|       "version": "4.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", | ||||
|       "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", | ||||
|       "dev": true | ||||
|       "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" | ||||
|     }, | ||||
|     "y18n": { | ||||
|       "version": "4.0.0", | ||||
|  | ||||
| @ -21,6 +21,7 @@ | ||||
|     "express": "^4.17.1", | ||||
|     "express-session": "^1.17.1", | ||||
|     "mongoose": "^5.9.18", | ||||
|     "multer": "^1.4.2", | ||||
|     "passport": "^0.4.1", | ||||
|     "passport-local": "^1.0.0", | ||||
|     "session-file-store": "^1.4.0", | ||||
|  | ||||
| @ -1,3 +1,8 @@ | ||||
| <script> | ||||
|     import { stores } from '@sapper/app'; | ||||
|     const { session } = stores(); | ||||
| </script> | ||||
| 
 | ||||
| <style> | ||||
|     nav { | ||||
|         font-weight: bold; | ||||
| @ -48,6 +53,10 @@ | ||||
|     <div class="items"> | ||||
|         <div><a href="/"><img class="wordmark" src="/logo.png" alt="HowFeed.biz"></a></div> | ||||
|         <div class="filler"></div> | ||||
|         <div class="link"><a href="mailto:the_katze@naver.com">Contact Us</a></div> | ||||
|         {#if !$session.user} | ||||
|             <div class="link"><a href="mailto:the_katze@naver.com">Contact Us</a></div> | ||||
|         {:else} | ||||
|             <div class="link"><a href="/cms/logout">Logout</a></div> | ||||
|         {/if} | ||||
|     </div> | ||||
| </nav> | ||||
|  | ||||
| @ -7,7 +7,8 @@ const { SALT_WORK_FACTOR } = process.env; | ||||
| const { Schema } = mongoose; | ||||
| const UserSchema = new Schema({ | ||||
|     username: { type: String, required: true, index: { unique: true } }, | ||||
|     password: { type: String, required: true } | ||||
|     password: { type: String, required: true }, | ||||
|     realname: { type: String, required: true } | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										69
									
								
								src/routes/cms/create.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/routes/cms/create.svelte
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | ||||
| <script context="module"> | ||||
|     export async function preload(page, session) | ||||
|     { | ||||
|         if (!session.user) { | ||||
|             return this.redirect(302, '/cms/login'); | ||||
|         } | ||||
|         return { user: session.user }; | ||||
|     } | ||||
| </script> | ||||
| 
 | ||||
| <script> | ||||
|     import { stores } from '@sapper/app'; | ||||
|     import Editor from 'cl-editor/src/Editor.svelte'; | ||||
| 
 | ||||
|     const { session } = stores(); | ||||
| 
 | ||||
|     let editor, form; | ||||
|     let html; | ||||
| 
 | ||||
|     let actions = [ | ||||
|         'viewHtml', 'undo', 'redo', 'b', 'i', 'u', 'strike', 'sup', 'sub', 'h1', 'h2', 'p', 'blockquote', | ||||
|         'ol', 'ul', 'hr', 'left', 'right', 'center', 'justify', 'a', 'image', 'forecolor', 'backcolor', 'removeFormat', | ||||
|         { | ||||
|             name: 'fakeTweet', | ||||
|             icon: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24">' + | ||||
|                   '<path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.' + | ||||
|                   '951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797' + | ||||
|                   ' 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566' + | ||||
|                   '-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444' + | ||||
|                   ' 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 ' + | ||||
|                   '14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/></svg>', | ||||
|             title: 'Fake Tweet', | ||||
|             result: () => { | ||||
|                 editor.exec('insertText', '<FakeTweet message="SAD!" author="Donald J. Trump"' + | ||||
|                     ' verified likes=1488 replies=6969 handle="realDonaldTrump"' + | ||||
|                     ' avatar="https://pbs.twimg.com/profile_images/874276197357596672/kUuht00m_400x400.jpg" />'); | ||||
|             } | ||||
|         } | ||||
|     ]; | ||||
| 
 | ||||
|     async function submit() | ||||
|     { | ||||
|         html = editor.getHtml(true); | ||||
|         form.submit(); | ||||
|     } | ||||
| </script> | ||||
| 
 | ||||
| <style> | ||||
|     input[type=text] { | ||||
|         width: 70%; | ||||
|     } | ||||
| </style> | ||||
| 
 | ||||
| <svelte:head> | ||||
|     <title>Publish | HOWFEED.BIZ</title> | ||||
| </svelte:head> | ||||
| 
 | ||||
| <div class="content"> | ||||
|     <a href="/cms">< Back to Dashboard</a> | ||||
|     <h1>HowFeed Publisher</h1> | ||||
|     <form method="POST" action="/cms/article" bind:this={form}> | ||||
|         <input type="hidden" name="html" bind:value={html}> | ||||
|         <p>Article Title: <input type="text" name="title" required placeholder="How to Assassinate the Governor of California"></p> | ||||
|         <p>Article Author: <strong>{$session.user.realname}</strong></p> | ||||
|         <p>Article Header Image URL: <input type="text" name="image" required placeholder="http:// ..."></p> | ||||
|     </form> | ||||
|     <Editor bind:this={editor} {actions} /> | ||||
|     <button on:click={submit}>Submit</button> | ||||
| </div> | ||||
| @ -8,27 +8,13 @@ | ||||
|     } | ||||
| </script> | ||||
| 
 | ||||
| <script> | ||||
|     import { onMount } from 'svelte'; | ||||
|     import Editor from 'cl-editor/src/Editor.svelte'; | ||||
| 
 | ||||
|     let editor; | ||||
| 
 | ||||
|     function preview() | ||||
|     { | ||||
|         alert(editor.getHtml(true)); | ||||
|     } | ||||
| </script> | ||||
| 
 | ||||
| <svelte:head> | ||||
|     <title>Publish | HOWFEED.BIZ</title> | ||||
|     <title>Dashboard | HOWFEED.BIZ</title> | ||||
| </svelte:head> | ||||
| 
 | ||||
| <div class="content"> | ||||
|     <h1>HowFeed Publisher</h1> | ||||
|     <form method="POST" action="/cms/article"> | ||||
|         <Editor bind:this={editor} /> | ||||
|         <button on:click|preventDefault={preview}>Preview</button> | ||||
|         <button type="submit">Submit</button> | ||||
|     </form> | ||||
|     <h1>HowFeed Publisher Dashboard</h1> | ||||
|     <p><a href="/cms/create">Publish a new article</a></p> | ||||
|     <p><a href="/cms/update">Edit an existing article</a></p> | ||||
|     <p><a href="/cms/delete">Delete an article</a></p> | ||||
| </div> | ||||
|  | ||||
| @ -26,4 +26,5 @@ | ||||
|         <input required type="password" name="password" placeholder="Password"> | ||||
|         <button type="submit">Submit</button> | ||||
|     </form> | ||||
|     <p>Need an account first? <a href="/cms/register">Register</a></p> | ||||
| </div> | ||||
|  | ||||
| @ -1,7 +1,3 @@ | ||||
| <script> | ||||
|     let username, password, password_confirm; | ||||
| </script> | ||||
| 
 | ||||
| <style> | ||||
|     input { | ||||
|         display: block; | ||||
| @ -26,9 +22,10 @@ | ||||
| <div class="content"> | ||||
|     <h1>Register</h1> | ||||
|     <form method="POST" action="/cms/register"> | ||||
|         <input required type="text" name="username" bind:value={username} placeholder="Username"> | ||||
|         <input required type="password" name="password" bind:value={password} placeholder="Password"> | ||||
|         <input required type="password" name="password_confirm" bind:value={password_confirm} placeholder="Confirm Password"> | ||||
|         <input required type="text" name="realname" placeholder="Real Name"> | ||||
|         <input required type="text" name="username" placeholder="Username"> | ||||
|         <input required type="password" name="password" placeholder="Password"> | ||||
|         <input required type="password" name="password_confirm" placeholder="Confirm Password"> | ||||
|         <button type="submit">Submit</button> | ||||
|     </form> | ||||
| </div> | ||||
|  | ||||
| @ -81,13 +81,13 @@ express() | ||||
|                 })); | ||||
|             } | ||||
|         }, async (req, res) => { | ||||
|             let { username, password, password_confirm } = req.body; | ||||
|             if (!username || !password || !password_confirm) { | ||||
|             let { username, password, password_confirm, realname } = req.body; | ||||
|             if (!username || !password || !password_confirm || !realname) { | ||||
|                 res.writeHead(422, { | ||||
|                     'Content-Type': 'application/json' | ||||
|                 }); | ||||
|                 res.end(JSON.stringify({ | ||||
|                     message: `You need to supply a username, password, and password_confirm.` | ||||
|                     message: `You need to supply a username, real name, password, and password confirmation.` | ||||
|                 })); | ||||
|                 return false; | ||||
|             } | ||||
| @ -121,7 +121,7 @@ express() | ||||
|                     return false; | ||||
|                 } | ||||
|                 // password gets automatically hashed
 | ||||
|                 const newUser = await new User({ username, password }); | ||||
|                 const newUser = await new User({ username, realname, password }); | ||||
|                 await newUser.save(); | ||||
| 
 | ||||
|                 req.login(newUser, err => { | ||||
| @ -166,6 +166,27 @@ express() | ||||
|         }); | ||||
|     }) | ||||
| 
 | ||||
|     .post('/cms/article', | ||||
|         passport.authenticate('local'), | ||||
|         function(req, res, next) { | ||||
|             res.writeHead(200, { | ||||
|                 'Content-Type': 'application/json' | ||||
|             }); | ||||
|             res.end(JSON.stringify({ | ||||
|                 message: `ur a faget lol` | ||||
|             })); | ||||
|         }, | ||||
|         function(err, req, res, next) { | ||||
|             // handle error
 | ||||
|             res.writeHead(err.status || 500, { | ||||
|                 'Content-Type': 'application/json' | ||||
|             }); | ||||
|             res.end(JSON.stringify({ | ||||
|                 message: err.message | ||||
|             })); | ||||
|         } | ||||
|     ) | ||||
| 
 | ||||
|     .use(compression({ threshold: 0 })) | ||||
|     .use(sirv('static', { dev })) | ||||
|     .use(sapper.middleware({ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user