From 2a5cab300ebaf2e7afadae2ef2227c379606fa1c Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 3 May 2017 21:18:22 +0100 Subject: [PATCH 01/32] Update Package.swift for Vapor2 --- Package.pins | 120 ++++++++++++++++++++++++++++++++------------------ Package.swift | 6 +-- 2 files changed, 81 insertions(+), 45 deletions(-) diff --git a/Package.pins b/Package.pins index 258e18c..d435237 100644 --- a/Package.pins +++ b/Package.pins @@ -2,154 +2,190 @@ "autoPin": true, "pins": [ { - "package": "CLibreSSL", + "package": "Auth", "reason": null, - "repositoryURL": "https://github.com/vapor/clibressl.git", - "version": "1.0.0" + "repositoryURL": "https://github.com/vapor/auth.git", + "version": "1.0.0-beta.1" + }, + { + "package": "AuthProvider", + "reason": null, + "repositoryURL": "https://github.com/vapor/auth-provider.git", + "version": "1.0.0-beta.3" + }, + { + "package": "BCrypt", + "reason": null, + "repositoryURL": "https://github.com/vapor/bcrypt.git", + "version": "1.0.0-beta.1" + }, + { + "package": "Bits", + "reason": null, + "repositoryURL": "https://github.com/vapor/bits.git", + "version": "1.0.0-beta.6" + }, + { + "package": "CTLS", + "reason": null, + "repositoryURL": "https://github.com/vapor/ctls.git", + "version": "1.0.0-beta.4" }, { "package": "Console", "reason": null, "repositoryURL": "https://github.com/vapor/console.git", - "version": "1.0.2" + "version": "2.0.0-beta.6" }, { "package": "Core", "reason": null, "repositoryURL": "https://github.com/vapor/core.git", - "version": "1.1.1" + "version": "2.0.0-beta.9" }, { "package": "Crypto", "reason": null, "repositoryURL": "https://github.com/vapor/crypto.git", - "version": "1.1.0" + "version": "2.0.0-beta.1" + }, + { + "package": "Debugging", + "reason": null, + "repositoryURL": "https://github.com/vapor/debugging.git", + "version": "1.0.0-beta.1" }, { "package": "Engine", "reason": null, "repositoryURL": "https://github.com/vapor/engine.git", - "version": "1.3.12" + "version": "2.0.0-beta.4" }, { "package": "Fluent", "reason": null, "repositoryURL": "https://github.com/vapor/fluent.git", - "version": "1.4.3" + "version": "2.0.0-beta.25" }, { - "package": "JSON", + "package": "FluentProvider", "reason": null, - "repositoryURL": "https://github.com/vapor/json.git", - "version": "1.0.6" + "repositoryURL": "https://github.com/vapor/fluent-provider.git", + "version": "1.0.0-beta.13" }, { - "package": "Jay", + "package": "JSON", "reason": null, - "repositoryURL": "https://github.com/DanToml/Jay.git", - "version": "1.0.1" + "repositoryURL": "https://github.com/vapor/json.git", + "version": "2.0.0-beta.3" }, { "package": "Leaf", "reason": null, "repositoryURL": "https://github.com/vapor/leaf.git", - "version": "1.0.7" + "version": "2.0.0-beta.7" }, { "package": "LeafMarkdown", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/LeafMarkdown.git", - "version": "0.2.1" + "version": "0.3.0-beta.5" + }, + { + "package": "LeafProvider", + "reason": null, + "repositoryURL": "https://github.com/vapor/leaf-provider.git", + "version": "1.0.0-beta.4" }, { "package": "Multipart", "reason": null, "repositoryURL": "https://github.com/vapor/multipart.git", - "version": "1.0.3" + "version": "2.0.0-beta.2" }, { "package": "Node", "reason": null, "repositoryURL": "https://github.com/vapor/node.git", - "version": "1.0.1" - }, - { - "package": "Paginator", - "reason": null, - "repositoryURL": "https://github.com/nodes-vapor/paginator", - "version": "0.4.4" + "version": "2.0.0-beta.1" }, { "package": "PathIndexable", "reason": null, "repositoryURL": "https://github.com/vapor/path-indexable.git", - "version": "1.0.0" + "version": "2.0.0-beta.1" }, { - "package": "Polymorphic", + "package": "Random", "reason": null, - "repositoryURL": "https://github.com/vapor/polymorphic.git", - "version": "1.0.1" + "repositoryURL": "https://github.com/vapor/random.git", + "version": "1.0.0-beta.3" }, { "package": "Routing", "reason": null, "repositoryURL": "https://github.com/vapor/routing.git", - "version": "1.1.0" + "version": "2.0.0-beta.3" }, { - "package": "Socks", + "package": "SQLite", + "reason": null, + "repositoryURL": "https://github.com/vapor/sqlite.git", + "version": "2.0.0-beta.1" + }, + { + "package": "Sockets", "reason": null, "repositoryURL": "https://github.com/vapor/socks.git", - "version": "1.2.7" + "version": "2.0.0-beta.5" }, { "package": "SteamPress", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/SteamPress.git", - "version": "0.10.0" + "version": "0.11.0-alpha.1" }, { "package": "SwiftMarkdown", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/SwiftMarkdown.git", - "version": "0.1.4" + "version": "0.2.0" }, { "package": "SwiftSoup", "reason": null, "repositoryURL": "https://github.com/scinfu/SwiftSoup.git", - "version": "1.3.0" + "version": "1.3.2" }, { "package": "TLS", "reason": null, "repositoryURL": "https://github.com/vapor/tls.git", - "version": "1.1.2" + "version": "2.0.0-beta.4" }, { - "package": "Turnstile", + "package": "Validation", "reason": null, - "repositoryURL": "https://github.com/stormpath/Turnstile.git", - "version": "1.0.6" + "repositoryURL": "https://github.com/vapor/validation.git", + "version": "0.2.0" }, { "package": "Vapor", "reason": null, "repositoryURL": "https://github.com/vapor/vapor.git", - "version": "1.5.14" + "version": "2.0.0-beta.23" }, { "package": "VaporSecurityHeaders", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/VaporSecurityHeaders.git", - "version": "0.3.0" + "version": "0.4.0-beta.3" }, { "package": "cmark", "reason": null, - "repositoryURL": "https://github.com/brokenhandsio/cmark.git", - "version": "0.26.2" + "repositoryURL": "https://github.com/brokenhandsio/cmark-gfm.git", + "version": "1.0.0" } ], "version": 1 diff --git a/Package.swift b/Package.swift index 6670a53..34f8a5c 100644 --- a/Package.swift +++ b/Package.swift @@ -3,9 +3,9 @@ import PackageDescription let package = Package( name: "SteamPressExample", dependencies: [ - .Package(url: "https://github.com/vapor/vapor.git", majorVersion: 1), - .Package(url: "https://github.com/brokenhandsio/SteamPress.git", majorVersion: 0), - .Package(url: "https://github.com/brokenhandsio/VaporSecurityHeaders.git", majorVersion: 0), + .Package(url: "https://github.com/vapor/vapor.git", Version(2,0,0, prereleaseIdentifiers: ["beta"])), + .Package(url: "https://github.com/brokenhandsio/SteamPress.git", Version(0,11,0, prereleaseIdentifiers: ["alpha"])), + .Package(url: "https://github.com/brokenhandsio/VaporSecurityHeaders.git", Version(0,4,0, prereleaseIdentifiers: ["beta"])), ], exclude: [ "Config", From 74bbb22ba28ca23806c6d8e87397eeb5aabe1980 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 3 May 2017 21:27:47 +0100 Subject: [PATCH 02/32] Start porting code over to Vapor 2 --- Sources/App/BlogAbortMiddleware.swift | 152 +++++++++++++------------- Sources/App/main.swift | 56 +++++----- 2 files changed, 106 insertions(+), 102 deletions(-) diff --git a/Sources/App/BlogAbortMiddleware.swift b/Sources/App/BlogAbortMiddleware.swift index d27d7d9..6e7c77d 100644 --- a/Sources/App/BlogAbortMiddleware.swift +++ b/Sources/App/BlogAbortMiddleware.swift @@ -1,76 +1,76 @@ -import HTTP -import Vapor - -/** - Handles the various Abort errors that can be thrown - in any Vapor closure. - - To stop this behavior, remove the - AbortMiddleware for the Droplet's `middleware` array. - */ -public class BlogAbortMiddleware: Middleware { - - let viewRenderer: ViewRenderer - let environment: Environment - let log: LogProtocol? - - public init(viewRenderer: ViewRenderer, environment: Environment, log: LogProtocol?) { - self.viewRenderer = viewRenderer - self.environment = environment - self.log = log - } - - public func respond(to request: Request, chainingTo chain: Responder) throws -> Response { - do { - return try chain.respond(to: request) - } catch let error as AbortError { - return try errorResponse(request, error) - } catch { - let errorType = type(of: error) - let message = "\(errorType): \(error)" - do { - return try errorResponse(request, .internalServerError, message) - } catch { - let response = Response(status: .internalServerError, body: "There was an internal server error, please try again later.".bytes) - return response - } - } - } - - // MARK: Private - - private func errorResponse(_ request: Request, _ status: Status, _ message: String) throws -> Response { - let error = Abort.custom(status: status, message: message) - return try errorResponse(request, error) - } - - private func errorResponse(_ request: Request, _ error: AbortError) throws -> Response { - self.log?.error("Uncaught Error: \(type(of: error)).\(error)") - - var params: [String: NodeRepresentable] = [ - "url": request.uri.description.makeNode(), - "code": try error.code.makeNode(), - "error": true.makeNode() - ] - - if environment == .production { - params["message"] = error.code < 500 ? error.message : "Something went wrong" - } - else { - params["message"] = error.message.makeNode() - params["metadata"] = error.metadata?.makeNode() - } - - if request.accept.prefers("html") { - let body = try viewRenderer.make(error.code == 404 ? "404" : "serverError", try params.makeNode()).data - return Response(status: Status(officialCode: error.code) ?? .internalServerError, headers: [ - "Content-Type": "text/html; charset=utf-8" - ], body: .data(body)) - } - else { - let response = try Response(status: error.status, json: JSON(node: params)) - return response - } - - } -} +//import HTTP +//import Vapor +// +///** +// Handles the various Abort errors that can be thrown +// in any Vapor closure. +// +// To stop this behavior, remove the +// AbortMiddleware for the Droplet's `middleware` array. +// */ +//public class BlogAbortMiddleware: Middleware { +// +// let viewRenderer: ViewRenderer +// let environment: Environment +// let log: LogProtocol? +// +// public init(viewRenderer: ViewRenderer, environment: Environment, log: LogProtocol?) { +// self.viewRenderer = viewRenderer +// self.environment = environment +// self.log = log +// } +// +// public func respond(to request: Request, chainingTo chain: Responder) throws -> Response { +// do { +// return try chain.respond(to: request) +// } catch let error as AbortError { +// return try errorResponse(request, error) +// } catch { +// let errorType = type(of: error) +// let message = "\(errorType): \(error)" +// do { +// return try errorResponse(request, .internalServerError, message) +// } catch { +// let response = Response(status: .internalServerError, body: "There was an internal server error, please try again later.".bytes) +// return response +// } +// } +// } +// +// // MARK: Private +// +// private func errorResponse(_ request: Request, _ status: Status, _ message: String) throws -> Response { +// let error = Abort.custom(status: status, message: message) +// return try errorResponse(request, error) +// } +// +// private func errorResponse(_ request: Request, _ error: AbortError) throws -> Response { +// self.log?.error("Uncaught Error: \(type(of: error)).\(error)") +// +// var params: [String: NodeRepresentable] = [ +// "url": request.uri.description.makeNode(), +// "code": try error.code.makeNode(), +// "error": true.makeNode() +// ] +// +// if environment == .production { +// params["message"] = error.code < 500 ? error.message : "Something went wrong" +// } +// else { +// params["message"] = error.message.makeNode() +// params["metadata"] = error.metadata?.makeNode() +// } +// +// if request.accept.prefers("html") { +// let body = try viewRenderer.make(error.code == 404 ? "404" : "serverError", try params.makeNode()).data +// return Response(status: Status(officialCode: error.code) ?? .internalServerError, headers: [ +// "Content-Type": "text/html; charset=utf-8" +// ], body: .data(body)) +// } +// else { +// let response = try Response(status: error.status, json: JSON(node: params)) +// return response +// } +// +// } +//} diff --git a/Sources/App/main.swift b/Sources/App/main.swift index 345d1b3..c58884c 100644 --- a/Sources/App/main.swift +++ b/Sources/App/main.swift @@ -5,48 +5,52 @@ import SteamPress import Foundation import VaporSecurityHeaders -let drop = Droplet() -let database = Database(MemoryDriver()) -drop.database = database - -let memory = MemorySessions() -let sessions = SessionsMiddleware(sessions: memory) -drop.middleware.append(sessions) - -let disqusName = drop.config["disqus", "disqusName"]?.string ?? "*" +let config = try Config() +let disqusName = config["disqus", "disqusName"]?.string ?? "*" var cspConfig = "default-src 'none'; script-src 'self' https://static.brokenhands.io https://cdn.jsdelivr.net/ https://connect.facebook.net/ https://publish.twitter.com cdn.syndication.twimg.com platform.twitter.com https://platform.linkedin.com https://ajax.googleapis.com/ https://cdnjs.cloudflare.com/ https://maxcdn.bootstrapcdn.com/ https://\(disqusName).disqus.com/ https://a.disquscdn.com/; style-src 'self' https://cdn.jsdelivr.net/ *.twimg.com platform.twitter.com https://maxcdn.bootstrapcdn.com/ https://a.disquscdn.com/ https://cdnjs.cloudflare.com/ajax/libs/select2/; img-src 'self' data: https://static.brokenhands.io https://www.facebook.com cdn.syndication.twimg.com syndication.twitter.com *.twimg.com platform.twitter.com https://referrer.disqus.com/ https://a.disquscdn.com/; connect-src 'self' https://links.services.disqus.com/; font-src https://maxcdn.bootstrapcdn.com/; child-src https://disqus.com/ syndication.twitter.com platform.twitter.com www.facebook.com staticxx.facebook.com; form-action 'self'; base-uri 'self'; require-sri-for script style;" -if let reportUri = drop.config["csp", "report-uri"]?.string { +if let reportUri = config["csp", "report-uri"]?.string { cspConfig += " report-uri \(reportUri);" } -if drop.environment == .production || drop.environment == .test { +if config.environment == .production || config.environment == .test { cspConfig += " upgrade-insecure-requests; block-all-mixed-content;" } let referrerPolicy = ReferrerPolicyConfiguration(.strictOriginWhenCrossOrigin) -let securityHeaders = SecurityHeaders(contentSecurityPolicyConfiguration: ContentSecurityPolicyConfiguration(value: cspConfig), referrerPolicyConfiguration: referrerPolicy) -drop.middleware.append(securityHeaders) +let securityHeaders = SecurityHeadersFactory().with(server: ServerConfiguration(value: "brokenhands.io")).with(contentSecurityPolicy: ContentSecurityPolicyConfiguration(value: cspConfig)).with(referrerPolicy: referrerPolicy) +config.addConfigurable(middleware: securityHeaders.builder(), name: "security-headers") + +//let abort = BlogAbortMiddleware(viewRenderer: drop.view, environment: drop.environment, log: drop.log) +//drop.middleware.insert(abort, at: 0) + + +try config.addProvider(SteamPress.Provider.self) + +let drop = try Droplet(config) +let database = try Database(MemoryDriver()) + + -let abort = BlogAbortMiddleware(viewRenderer: drop.view, environment: drop.environment, log: drop.log) -drop.middleware.insert(abort, at: 0) +//let memory = MemorySessions() +//let sessions = SessionsMiddleware(sessions: memory) +//drop.middleware.append(sessions) -try drop.addProvider(SteamPress.Provider.self) drop.get { req in - var posts = try BlogPost.query().filter("published", true).sort("created", .descending).limit(3).all() + var posts = try BlogPost.makeQuery().filter("published", true).sort("created", .descending).limit(3).all() - var parameters = [ - "uri": req.uri.description.makeNode() + var parameters: [String: NodeRepresentable] = [ + "uri": req.uri.description ] if posts.count > 0 { - parameters["posts"] = try posts.makeNode(context: BlogPostContext.shortSnippet) + parameters["posts"] = try posts.makeNode(in: BlogPostContext.shortSnippet) } if let twitterHandle = drop.config["twitter", "siteHandle"]?.string { - parameters["site_twitter_handle"] = twitterHandle.makeNode() + parameters["site_twitter_handle"] = twitterHandle } return try drop.view.make("index", parameters) @@ -54,17 +58,17 @@ drop.get { req in drop.get("about") { req in - var parameters = [ - "about_page": true.makeNode(), - "uri": req.uri.description.makeNode() + var parameters: [String: NodeRepresentable] = [ + "about_page": true, + "uri": req.uri.description ] if let twitterHandle = drop.config["twitter", "siteHandle"]?.string { - parameters["site_twitter_handle"] = twitterHandle.makeNode() + parameters["site_twitter_handle"] = twitterHandle } return try drop.view.make("about", parameters) } -drop.run() +try drop.run() From 0fd8095f62044eed5084c436400331093346e2c7 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 3 May 2017 21:30:37 +0100 Subject: [PATCH 03/32] Update crypto config for Vapor 2 --- Config/crypto.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Config/crypto.json b/Config/crypto.json index bd5daa1..ef160b9 100644 --- a/Config/crypto.json +++ b/Config/crypto.json @@ -1,11 +1,13 @@ { "hash": { "method": "sha256", - "key": "password" + "encoding": "hex", + "key": "0000000000000000" }, + "cipher": { - "method": "chacha20", - "key": "passwordpasswordpasswordpassword", - "iv": "password" + "method": "aes256", + "encoding": "base64", + "key": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" } } From 8500b6ffb0fcfab4fc3faeaf520820382bd94a34 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 3 May 2017 21:33:13 +0100 Subject: [PATCH 04/32] Better crypto keys --- Config/crypto.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/crypto.json b/Config/crypto.json index ef160b9..c28ba43 100644 --- a/Config/crypto.json +++ b/Config/crypto.json @@ -2,12 +2,12 @@ "hash": { "method": "sha256", "encoding": "hex", - "key": "0000000000000000" + "key": "fdea1cef4c46ebO2" }, "cipher": { "method": "aes256", "encoding": "base64", - "key": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" + "key": "9vGTTv7CiDC3FiRxGrh1nKmz13lt1AN0myV+Aziw5HQ=" } } From 6d6662831f9b94dd614dc6a2d77e68fa8a002775 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 3 May 2017 21:36:49 +0100 Subject: [PATCH 05/32] Leaf is a separate package in Vapor 2 --- Config/droplet.json | 3 ++- Package.swift | 1 + Sources/App/main.swift | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Config/droplet.json b/Config/droplet.json index 2bce407..a2ad6bd 100644 --- a/Config/droplet.json +++ b/Config/droplet.json @@ -5,6 +5,7 @@ "log": "console", "hash": "crypto", "cipher": "crypto", + "view": "leaf", "middleware": { "server": [ "file", @@ -14,7 +15,7 @@ "sessions" ], "client": [ - + ] } } diff --git a/Package.swift b/Package.swift index 34f8a5c..c9e75f1 100644 --- a/Package.swift +++ b/Package.swift @@ -6,6 +6,7 @@ let package = Package( .Package(url: "https://github.com/vapor/vapor.git", Version(2,0,0, prereleaseIdentifiers: ["beta"])), .Package(url: "https://github.com/brokenhandsio/SteamPress.git", Version(0,11,0, prereleaseIdentifiers: ["alpha"])), .Package(url: "https://github.com/brokenhandsio/VaporSecurityHeaders.git", Version(0,4,0, prereleaseIdentifiers: ["beta"])), + .Package(url: "https://github.com/vapor/leaf-provider.git", Version(1,0,0, prereleaseIdentifiers: ["beta"])) ], exclude: [ "Config", diff --git a/Sources/App/main.swift b/Sources/App/main.swift index c58884c..e6f09ef 100644 --- a/Sources/App/main.swift +++ b/Sources/App/main.swift @@ -4,6 +4,7 @@ import Sessions import SteamPress import Foundation import VaporSecurityHeaders +import LeafProvider let config = try Config() let disqusName = config["disqus", "disqusName"]?.string ?? "*" @@ -27,6 +28,7 @@ config.addConfigurable(middleware: securityHeaders.builder(), name: "security-he try config.addProvider(SteamPress.Provider.self) +try config.addProvider(LeafProvider.Provider.self) let drop = try Droplet(config) let database = try Database(MemoryDriver()) From b9b8c2a1f64dd4d659df666437168277848102e8 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Thu, 4 May 2017 07:57:46 +0100 Subject: [PATCH 06/32] Add in the database --- Config/fluent.json | 25 +++++++++++++++++++++++++ Sources/App/main.swift | 2 ++ 2 files changed, 27 insertions(+) create mode 100644 Config/fluent.json diff --git a/Config/fluent.json b/Config/fluent.json new file mode 100644 index 0000000..37b0d1d --- /dev/null +++ b/Config/fluent.json @@ -0,0 +1,25 @@ +{ + "driver": "memory", + + "//": "Naming convention to use for creating foreign id keys,", + "//": "e.g., `user_id`", + "//": "`camelCase` option is also available.", + "keyNamingConvention": "snake_case", + + "//": "Name of the table Fluent uses to track migrations", + "migrationEntityName": "fluent", + + "//": "Character used to join pivot tables, e.g., `user_pet`", + "pivotNameConnector": "_", + + "//": "If true, foreign keys will automatically be added", + "//": "to any `builder.foreignId(...)` calls.", + "autoForeignKeys": true, + + "//": "Key to specify page number for paginated responses", + "//": "e.g., `?page=2` ", + "defaultPageKey": "page", + + "//": "Default page size if not otherwise specified on models", + "defaultPageSize": 10 +} diff --git a/Sources/App/main.swift b/Sources/App/main.swift index e6f09ef..675801e 100644 --- a/Sources/App/main.swift +++ b/Sources/App/main.swift @@ -5,6 +5,7 @@ import SteamPress import Foundation import VaporSecurityHeaders import LeafProvider +import FluentProvider let config = try Config() let disqusName = config["disqus", "disqusName"]?.string ?? "*" @@ -29,6 +30,7 @@ config.addConfigurable(middleware: securityHeaders.builder(), name: "security-he try config.addProvider(SteamPress.Provider.self) try config.addProvider(LeafProvider.Provider.self) +try config.addProvider(FluentProvider.Provider.self) let drop = try Droplet(config) let database = try Database(MemoryDriver()) From 0eb773114792c5c9d752f24e4300f742089c15e4 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Thu, 4 May 2017 13:05:15 +0100 Subject: [PATCH 07/32] Get middleware working again --- Config/droplet.json | 22 ++++++++++------------ Package.pins | 4 ++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/Config/droplet.json b/Config/droplet.json index a2ad6bd..c9727a3 100644 --- a/Config/droplet.json +++ b/Config/droplet.json @@ -6,16 +6,14 @@ "hash": "crypto", "cipher": "crypto", "view": "leaf", - "middleware": { - "server": [ - "file", - "validation", - "type-safe", - "date", - "sessions" - ], - "client": [ - - ] - } + "middleware": [ + "error", + "date", + "file", + "sessions", + "persist" + ], + "commands": [ + "prepare" + ] } diff --git a/Package.pins b/Package.pins index d435237..435a13a 100644 --- a/Package.pins +++ b/Package.pins @@ -59,7 +59,7 @@ "package": "Engine", "reason": null, "repositoryURL": "https://github.com/vapor/engine.git", - "version": "2.0.0-beta.4" + "version": "2.0.0-beta.5" }, { "package": "Fluent", @@ -143,7 +143,7 @@ "package": "SteamPress", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/SteamPress.git", - "version": "0.11.0-alpha.1" + "version": "0.11.0-alpha.2" }, { "package": "SwiftMarkdown", From 603c0cc1142baa7dabddf75abdbab15ef427de9c Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Thu, 4 May 2017 21:02:41 +0100 Subject: [PATCH 08/32] Remove paginator leaf tag for now --- Package.pins | 2 +- Resources/Views/blog/blog.leaf | 1 - Resources/Views/blog/profile.leaf | 1 - Resources/Views/blog/tag.leaf | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Package.pins b/Package.pins index 435a13a..e38fb43 100644 --- a/Package.pins +++ b/Package.pins @@ -143,7 +143,7 @@ "package": "SteamPress", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/SteamPress.git", - "version": "0.11.0-alpha.2" + "version": "0.11.0-alpha.3" }, { "package": "SwiftMarkdown", diff --git a/Resources/Views/blog/blog.leaf b/Resources/Views/blog/blog.leaf index 6176300..07fc1d9 100644 --- a/Resources/Views/blog/blog.leaf +++ b/Resources/Views/blog/blog.leaf @@ -59,7 +59,6 @@ } - #paginator(posts) } ##else() { diff --git a/Resources/Views/blog/profile.leaf b/Resources/Views/blog/profile.leaf index 56658ee..4602ce1 100644 --- a/Resources/Views/blog/profile.leaf +++ b/Resources/Views/blog/profile.leaf @@ -107,7 +107,6 @@ } - #paginator(posts) } ##else() {

There haven't been any blog posts yet!

diff --git a/Resources/Views/blog/tag.leaf b/Resources/Views/blog/tag.leaf index 49b4a6f..358575e 100644 --- a/Resources/Views/blog/tag.leaf +++ b/Resources/Views/blog/tag.leaf @@ -65,7 +65,6 @@ } - #paginator(posts) } ##else() {

There haven't been any blog posts yet!

From 16e5ced19b3544874e4481f524bcb57e05c22a2f Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Fri, 5 May 2017 01:04:35 +0100 Subject: [PATCH 09/32] Re-enable Vapor Security Headers --- Config/droplet.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Config/droplet.json b/Config/droplet.json index c9727a3..67f0aed 100644 --- a/Config/droplet.json +++ b/Config/droplet.json @@ -7,6 +7,7 @@ "cipher": "crypto", "view": "leaf", "middleware": [ + "security-headers", "error", "date", "file", From 0b9145d5e459c948d18af0f063b0ab7ef47fd7ca Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Fri, 5 May 2017 01:30:59 +0100 Subject: [PATCH 10/32] Get custom 404 page working again --- Config/droplet.json | 2 +- Sources/App/BlogAbortMiddleware.swift | 76 ----------- Sources/App/BlogErrorMiddleware.swift | 175 ++++++++++++++++++++++++++ Sources/App/main.swift | 11 +- 4 files changed, 177 insertions(+), 87 deletions(-) delete mode 100644 Sources/App/BlogAbortMiddleware.swift create mode 100644 Sources/App/BlogErrorMiddleware.swift diff --git a/Config/droplet.json b/Config/droplet.json index 67f0aed..2aaf966 100644 --- a/Config/droplet.json +++ b/Config/droplet.json @@ -8,7 +8,7 @@ "view": "leaf", "middleware": [ "security-headers", - "error", + "blog-error", "date", "file", "sessions", diff --git a/Sources/App/BlogAbortMiddleware.swift b/Sources/App/BlogAbortMiddleware.swift deleted file mode 100644 index 6e7c77d..0000000 --- a/Sources/App/BlogAbortMiddleware.swift +++ /dev/null @@ -1,76 +0,0 @@ -//import HTTP -//import Vapor -// -///** -// Handles the various Abort errors that can be thrown -// in any Vapor closure. -// -// To stop this behavior, remove the -// AbortMiddleware for the Droplet's `middleware` array. -// */ -//public class BlogAbortMiddleware: Middleware { -// -// let viewRenderer: ViewRenderer -// let environment: Environment -// let log: LogProtocol? -// -// public init(viewRenderer: ViewRenderer, environment: Environment, log: LogProtocol?) { -// self.viewRenderer = viewRenderer -// self.environment = environment -// self.log = log -// } -// -// public func respond(to request: Request, chainingTo chain: Responder) throws -> Response { -// do { -// return try chain.respond(to: request) -// } catch let error as AbortError { -// return try errorResponse(request, error) -// } catch { -// let errorType = type(of: error) -// let message = "\(errorType): \(error)" -// do { -// return try errorResponse(request, .internalServerError, message) -// } catch { -// let response = Response(status: .internalServerError, body: "There was an internal server error, please try again later.".bytes) -// return response -// } -// } -// } -// -// // MARK: Private -// -// private func errorResponse(_ request: Request, _ status: Status, _ message: String) throws -> Response { -// let error = Abort.custom(status: status, message: message) -// return try errorResponse(request, error) -// } -// -// private func errorResponse(_ request: Request, _ error: AbortError) throws -> Response { -// self.log?.error("Uncaught Error: \(type(of: error)).\(error)") -// -// var params: [String: NodeRepresentable] = [ -// "url": request.uri.description.makeNode(), -// "code": try error.code.makeNode(), -// "error": true.makeNode() -// ] -// -// if environment == .production { -// params["message"] = error.code < 500 ? error.message : "Something went wrong" -// } -// else { -// params["message"] = error.message.makeNode() -// params["metadata"] = error.metadata?.makeNode() -// } -// -// if request.accept.prefers("html") { -// let body = try viewRenderer.make(error.code == 404 ? "404" : "serverError", try params.makeNode()).data -// return Response(status: Status(officialCode: error.code) ?? .internalServerError, headers: [ -// "Content-Type": "text/html; charset=utf-8" -// ], body: .data(body)) -// } -// else { -// let response = try Response(status: error.status, json: JSON(node: params)) -// return response -// } -// -// } -//} diff --git a/Sources/App/BlogErrorMiddleware.swift b/Sources/App/BlogErrorMiddleware.swift new file mode 100644 index 0000000..ddfd8ec --- /dev/null +++ b/Sources/App/BlogErrorMiddleware.swift @@ -0,0 +1,175 @@ +import Vapor +import HTTP + +public final class BlogErrorMiddleware: Middleware { + let log: LogProtocol + let environment: Environment + let viewRenderer: ViewRenderer + public init(environment: Environment, log: LogProtocol, viewRenderer: ViewRenderer) { + self.log = log + self.environment = environment + self.viewRenderer = viewRenderer + } + + public func respond(to req: Request, chainingTo next: Responder) throws -> Response { + do { + return try next.respond(to: req) + } catch { + log.error(error) + return make(with: req, for: error) + } + } + + public func make(with req: Request, for error: Error) -> Response { + guard !req.accept.prefers("html") else { + let status: Status = Status(error) + if status == .notFound { + do { + return try viewRenderer.make("404", Node([:])).makeResponse() + } + catch { /* swallow so we return the default view */ } + } +// let bytes = errorView.render( +// code: status.statusCode, +// message: status.reasonPhrase +// ) + return View(bytes: Bytes()).makeResponse() + } + + let status = Status(error) + let response = Response(status: status) + response.json = JSON(error, env: environment) + return response + } +} + +extension BlogErrorMiddleware: ConfigInitializable { + public convenience init(config: Config) throws { + let log = try config.resolveLog() + let viewRenderer = try config.resolveView() + self.init(environment: config.environment, log: log, viewRenderer: viewRenderer) + } +} + +extension Status { + internal init(_ error: Error) { + if let abort = error as? AbortError { + self = abort.status + } else { + self = .internalServerError + } + } +} + +extension JSON { + fileprivate init(_ error: Error, env: Environment) { + let status = Status(error) + + var json = JSON(["error": true]) + if let abort = error as? AbortError { + try? json.set("reason", abort.reason) + } else { + try? json.set("reason", status.reasonPhrase) + } + + guard env != .production else { + self = json + return + } + + if env != .production { + if let abort = error as? AbortError { + try? json.set("metadata", abort.metadata) + } + + if let debug = error as? Debuggable { + try? json.set("debugReason", debug.reason) + try? json.set("identifier", debug.fullIdentifier) + try? json.set("possibleCauses", debug.possibleCauses) + try? json.set("suggestedFixes", debug.suggestedFixes) + try? json.set("documentationLinks", debug.documentationLinks) + try? json.set("stackOverflowQuestions", debug.stackOverflowQuestions) + try? json.set("gitHubIssues", debug.gitHubIssues) + } + } + + self = json + } +} + +//import HTTP +//import Vapor +// +///** +// Handles the various Abort errors that can be thrown +// in any Vapor closure. +// +// To stop this behavior, remove the +// AbortMiddleware for the Droplet's `middleware` array. +// */ +//public class BlogAbortMiddleware: Middleware { +// +// let viewRenderer: ViewRenderer +// let environment: Environment +// let log: LogProtocol? +// +// public init(viewRenderer: ViewRenderer, environment: Environment, log: LogProtocol?) { +// self.viewRenderer = viewRenderer +// self.environment = environment +// self.log = log +// } +// +// public func respond(to request: Request, chainingTo chain: Responder) throws -> Response { +// do { +// return try chain.respond(to: request) +// } catch let error as AbortError { +// return try errorResponse(request, error) +// } catch { +// let errorType = type(of: error) +// let message = "\(errorType): \(error)" +// do { +// return try errorResponse(request, .internalServerError, message) +// } catch { +// let response = Response(status: .internalServerError, body: "There was an internal server error, please try again later.".bytes) +// return response +// } +// } +// } +// +// // MARK: Private +// +// private func errorResponse(_ request: Request, _ status: Status, _ message: String) throws -> Response { +// let error = Abort.custom(status: status, message: message) +// return try errorResponse(request, error) +// } +// +// private func errorResponse(_ request: Request, _ error: AbortError) throws -> Response { +// self.log?.error("Uncaught Error: \(type(of: error)).\(error)") +// +// var params: [String: NodeRepresentable] = [ +// "url": request.uri.description.makeNode(), +// "code": try error.code.makeNode(), +// "error": true.makeNode() +// ] +// +// if environment == .production { +// params["message"] = error.code < 500 ? error.message : "Something went wrong" +// } +// else { +// params["message"] = error.message.makeNode() +// params["metadata"] = error.metadata?.makeNode() +// } +// +// if request.accept.prefers("html") { +// let body = try viewRenderer.make(error.code == 404 ? "404" : "serverError", try params.makeNode()).data +// return Response(status: Status(officialCode: error.code) ?? .internalServerError, headers: [ +// "Content-Type": "text/html; charset=utf-8" +// ], body: .data(body)) +// } +// else { +// let response = try Response(status: error.status, json: JSON(node: params)) +// return response +// } +// +// } +//} diff --git a/Sources/App/main.swift b/Sources/App/main.swift index 675801e..3b80458 100644 --- a/Sources/App/main.swift +++ b/Sources/App/main.swift @@ -23,9 +23,7 @@ let referrerPolicy = ReferrerPolicyConfiguration(.strictOriginWhenCrossOrigin) let securityHeaders = SecurityHeadersFactory().with(server: ServerConfiguration(value: "brokenhands.io")).with(contentSecurityPolicy: ContentSecurityPolicyConfiguration(value: cspConfig)).with(referrerPolicy: referrerPolicy) config.addConfigurable(middleware: securityHeaders.builder(), name: "security-headers") - -//let abort = BlogAbortMiddleware(viewRenderer: drop.view, environment: drop.environment, log: drop.log) -//drop.middleware.insert(abort, at: 0) +config.addConfigurable(middleware: BlogErrorMiddleware.init, name: "blog-error") try config.addProvider(SteamPress.Provider.self) @@ -35,13 +33,6 @@ try config.addProvider(FluentProvider.Provider.self) let drop = try Droplet(config) let database = try Database(MemoryDriver()) - - -//let memory = MemorySessions() -//let sessions = SessionsMiddleware(sessions: memory) -//drop.middleware.append(sessions) - - drop.get { req in var posts = try BlogPost.makeQuery().filter("published", true).sort("created", .descending).limit(3).all() From 82815d71868a6f46225d46a54bba671924c6729f Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Mon, 8 May 2017 20:17:17 +0100 Subject: [PATCH 11/32] Update package --- Package.pins | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Package.pins b/Package.pins index e38fb43..23cfb21 100644 --- a/Package.pins +++ b/Package.pins @@ -5,13 +5,13 @@ "package": "Auth", "reason": null, "repositoryURL": "https://github.com/vapor/auth.git", - "version": "1.0.0-beta.1" + "version": "1.0.0-beta.2" }, { "package": "AuthProvider", "reason": null, "repositoryURL": "https://github.com/vapor/auth-provider.git", - "version": "1.0.0-beta.3" + "version": "1.0.0-beta.4" }, { "package": "BCrypt", @@ -143,7 +143,7 @@ "package": "SteamPress", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/SteamPress.git", - "version": "0.11.0-alpha.3" + "version": "0.11.0-alpha.4" }, { "package": "SwiftMarkdown", From 7e2fc081a3cea2158dc2de9c9a030a52e8b10dcf Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Mon, 8 May 2017 20:25:42 +0100 Subject: [PATCH 12/32] Add config files --- Config/csp.json | 3 +++ Config/disqus.json | 3 +++ Config/twitter.json | 3 +++ 3 files changed, 9 insertions(+) create mode 100644 Config/csp.json create mode 100644 Config/disqus.json create mode 100644 Config/twitter.json diff --git a/Config/csp.json b/Config/csp.json new file mode 100644 index 0000000..ab12cb0 --- /dev/null +++ b/Config/csp.json @@ -0,0 +1,3 @@ +{ + "report-uri": $CSP_REPORT_URI +} diff --git a/Config/disqus.json b/Config/disqus.json new file mode 100644 index 0000000..8f9586f --- /dev/null +++ b/Config/disqus.json @@ -0,0 +1,3 @@ +{ + "disqus.disqusName": $DISQUS_NAME +} diff --git a/Config/twitter.json b/Config/twitter.json new file mode 100644 index 0000000..c2676b6 --- /dev/null +++ b/Config/twitter.json @@ -0,0 +1,3 @@ +{ + "siteHandle": "brokenhandsio" +} From 894bbbc44b0fb0441823f6957b119c53ce241c74 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Mon, 8 May 2017 20:41:26 +0100 Subject: [PATCH 13/32] Move configs with secrets into Production so we don't have to set them in dev --- Config/csp.json | 3 --- Config/disqus.json | 3 --- 2 files changed, 6 deletions(-) delete mode 100644 Config/csp.json delete mode 100644 Config/disqus.json diff --git a/Config/csp.json b/Config/csp.json deleted file mode 100644 index ab12cb0..0000000 --- a/Config/csp.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "report-uri": $CSP_REPORT_URI -} diff --git a/Config/disqus.json b/Config/disqus.json deleted file mode 100644 index 8f9586f..0000000 --- a/Config/disqus.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "disqus.disqusName": $DISQUS_NAME -} From 70def9ca82ebea455e54b9d5b2dcbcbf21689801 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Mon, 8 May 2017 21:00:10 +0100 Subject: [PATCH 14/32] Finish the Error middleware --- Config/production/csp.json | 3 +++ Config/production/disqus.json | 3 +++ Sources/App/BlogErrorMiddleware.swift | 10 +++++----- 3 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 Config/production/csp.json create mode 100644 Config/production/disqus.json diff --git a/Config/production/csp.json b/Config/production/csp.json new file mode 100644 index 0000000..ab12cb0 --- /dev/null +++ b/Config/production/csp.json @@ -0,0 +1,3 @@ +{ + "report-uri": $CSP_REPORT_URI +} diff --git a/Config/production/disqus.json b/Config/production/disqus.json new file mode 100644 index 0000000..8f9586f --- /dev/null +++ b/Config/production/disqus.json @@ -0,0 +1,3 @@ +{ + "disqus.disqusName": $DISQUS_NAME +} diff --git a/Sources/App/BlogErrorMiddleware.swift b/Sources/App/BlogErrorMiddleware.swift index ddfd8ec..c167eaf 100644 --- a/Sources/App/BlogErrorMiddleware.swift +++ b/Sources/App/BlogErrorMiddleware.swift @@ -29,11 +29,11 @@ public final class BlogErrorMiddleware: Middleware { } catch { /* swallow so we return the default view */ } } -// let bytes = errorView.render( -// code: status.statusCode, -// message: status.reasonPhrase -// ) - return View(bytes: Bytes()).makeResponse() + + let body = "

" + status.statusCode.description + "

" + status.reasonPhrase + "

" + let response = Response(status: status, body: .data(body.makeBytes())) + response.headers["Content-Type"] = "text/html; charset=utf-8" + return response } let status = Status(error) From d850181a116ec58de62c3ca6daceaf53e637f9fc Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Tue, 9 May 2017 08:24:23 +0100 Subject: [PATCH 15/32] Test bringing back paginator and removed old Middleware code --- Resources/Views/blog/blog.leaf | 2 +- Sources/App/BlogErrorMiddleware.swift | 77 --------------------------- 2 files changed, 1 insertion(+), 78 deletions(-) diff --git a/Resources/Views/blog/blog.leaf b/Resources/Views/blog/blog.leaf index 07fc1d9..506a2db 100644 --- a/Resources/Views/blog/blog.leaf +++ b/Resources/Views/blog/blog.leaf @@ -58,7 +58,7 @@ } - + #paginator(posts) } ##else() { diff --git a/Sources/App/BlogErrorMiddleware.swift b/Sources/App/BlogErrorMiddleware.swift index c167eaf..f94ad8f 100644 --- a/Sources/App/BlogErrorMiddleware.swift +++ b/Sources/App/BlogErrorMiddleware.swift @@ -96,80 +96,3 @@ extension JSON { self = json } } - -//import HTTP -//import Vapor -// -///** -// Handles the various Abort errors that can be thrown -// in any Vapor closure. -// -// To stop this behavior, remove the -// AbortMiddleware for the Droplet's `middleware` array. -// */ -//public class BlogAbortMiddleware: Middleware { -// -// let viewRenderer: ViewRenderer -// let environment: Environment -// let log: LogProtocol? -// -// public init(viewRenderer: ViewRenderer, environment: Environment, log: LogProtocol?) { -// self.viewRenderer = viewRenderer -// self.environment = environment -// self.log = log -// } -// -// public func respond(to request: Request, chainingTo chain: Responder) throws -> Response { -// do { -// return try chain.respond(to: request) -// } catch let error as AbortError { -// return try errorResponse(request, error) -// } catch { -// let errorType = type(of: error) -// let message = "\(errorType): \(error)" -// do { -// return try errorResponse(request, .internalServerError, message) -// } catch { -// let response = Response(status: .internalServerError, body: "There was an internal server error, please try again later.".bytes) -// return response -// } -// } -// } -// -// // MARK: Private -// -// private func errorResponse(_ request: Request, _ status: Status, _ message: String) throws -> Response { -// let error = Abort.custom(status: status, message: message) -// return try errorResponse(request, error) -// } -// -// private func errorResponse(_ request: Request, _ error: AbortError) throws -> Response { -// self.log?.error("Uncaught Error: \(type(of: error)).\(error)") -// -// var params: [String: NodeRepresentable] = [ -// "url": request.uri.description.makeNode(), -// "code": try error.code.makeNode(), -// "error": true.makeNode() -// ] -// -// if environment == .production { -// params["message"] = error.code < 500 ? error.message : "Something went wrong" -// } -// else { -// params["message"] = error.message.makeNode() -// params["metadata"] = error.metadata?.makeNode() -// } -// -// if request.accept.prefers("html") { -// let body = try viewRenderer.make(error.code == 404 ? "404" : "serverError", try params.makeNode()).data -// return Response(status: Status(officialCode: error.code) ?? .internalServerError, headers: [ -// "Content-Type": "text/html; charset=utf-8" -// ], body: .data(body)) -// } -// else { -// let response = try Response(status: error.status, json: JSON(node: params)) -// return response -// } -// -// } -//} From 4c5b60274462147b17bdf5d8d2b4fbf5791ef51c Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Fri, 12 May 2017 12:41:53 +0100 Subject: [PATCH 16/32] Bring back pagination to the author and tag pages --- Package.pins | 18 +++++++++--------- Resources/Views/blog/profile.leaf | 2 +- Resources/Views/blog/tag.leaf | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Package.pins b/Package.pins index 23cfb21..05bce64 100644 --- a/Package.pins +++ b/Package.pins @@ -11,7 +11,7 @@ "package": "AuthProvider", "reason": null, "repositoryURL": "https://github.com/vapor/auth-provider.git", - "version": "1.0.0-beta.4" + "version": "1.0.0-beta.5" }, { "package": "BCrypt", @@ -59,25 +59,25 @@ "package": "Engine", "reason": null, "repositoryURL": "https://github.com/vapor/engine.git", - "version": "2.0.0-beta.5" + "version": "2.0.0-beta.6" }, { "package": "Fluent", "reason": null, "repositoryURL": "https://github.com/vapor/fluent.git", - "version": "2.0.0-beta.25" + "version": "2.0.0-beta.27" }, { "package": "FluentProvider", "reason": null, "repositoryURL": "https://github.com/vapor/fluent-provider.git", - "version": "1.0.0-beta.13" + "version": "1.0.0-beta.15" }, { "package": "JSON", "reason": null, "repositoryURL": "https://github.com/vapor/json.git", - "version": "2.0.0-beta.3" + "version": "2.0.0-beta.5" }, { "package": "Leaf", @@ -107,7 +107,7 @@ "package": "Node", "reason": null, "repositoryURL": "https://github.com/vapor/node.git", - "version": "2.0.0-beta.1" + "version": "2.0.0-beta.6" }, { "package": "PathIndexable", @@ -125,7 +125,7 @@ "package": "Routing", "reason": null, "repositoryURL": "https://github.com/vapor/routing.git", - "version": "2.0.0-beta.3" + "version": "2.0.0-beta.5" }, { "package": "SQLite", @@ -137,7 +137,7 @@ "package": "Sockets", "reason": null, "repositoryURL": "https://github.com/vapor/socks.git", - "version": "2.0.0-beta.5" + "version": "2.0.0-beta.6" }, { "package": "SteamPress", @@ -173,7 +173,7 @@ "package": "Vapor", "reason": null, "repositoryURL": "https://github.com/vapor/vapor.git", - "version": "2.0.0-beta.23" + "version": "2.0.0-beta.25" }, { "package": "VaporSecurityHeaders", diff --git a/Resources/Views/blog/profile.leaf b/Resources/Views/blog/profile.leaf index 4602ce1..9c30f12 100644 --- a/Resources/Views/blog/profile.leaf +++ b/Resources/Views/blog/profile.leaf @@ -106,7 +106,7 @@ } - + #paginator(posts) } ##else() {

There haven't been any blog posts yet!

diff --git a/Resources/Views/blog/tag.leaf b/Resources/Views/blog/tag.leaf index 358575e..d57e53c 100644 --- a/Resources/Views/blog/tag.leaf +++ b/Resources/Views/blog/tag.leaf @@ -64,7 +64,7 @@ } - + #paginator(posts) } ##else() {

There haven't been any blog posts yet!

From 84e43407761a0b572c9b0aad05515bbe6afd4b20 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Fri, 12 May 2017 12:55:14 +0100 Subject: [PATCH 17/32] Blog's persist middleware has been renamed --- Config/droplet.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/droplet.json b/Config/droplet.json index 2aaf966..4e61cae 100644 --- a/Config/droplet.json +++ b/Config/droplet.json @@ -12,7 +12,7 @@ "date", "file", "sessions", - "persist" + "blog-persist" ], "commands": [ "prepare" From 53f6feaa3ec83d7580cfab1d2c10eefe4e9f4be4 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Fri, 12 May 2017 19:22:50 +0100 Subject: [PATCH 18/32] Package updates --- Package.pins | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Package.pins b/Package.pins index 05bce64..4f71b0c 100644 --- a/Package.pins +++ b/Package.pins @@ -107,7 +107,7 @@ "package": "Node", "reason": null, "repositoryURL": "https://github.com/vapor/node.git", - "version": "2.0.0-beta.6" + "version": "2.0.0-beta.7" }, { "package": "PathIndexable", @@ -143,7 +143,7 @@ "package": "SteamPress", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/SteamPress.git", - "version": "0.11.0-alpha.4" + "version": "0.11.0-alpha.7" }, { "package": "SwiftMarkdown", From ffcb0d44dc8577ffe242e3d3ea2ca9e05ffd096a Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Sun, 14 May 2017 22:11:35 +0100 Subject: [PATCH 19/32] Package updates --- Package.pins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.pins b/Package.pins index 4f71b0c..71022e9 100644 --- a/Package.pins +++ b/Package.pins @@ -143,7 +143,7 @@ "package": "SteamPress", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/SteamPress.git", - "version": "0.11.0-alpha.7" + "version": "0.11.0-alpha.8" }, { "package": "SwiftMarkdown", From f4eca72a9c2011b04a4c73162b35106247524e8a Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 17 May 2017 00:26:10 +0100 Subject: [PATCH 20/32] Remove trailing slash as the URI now includes that --- Resources/Views/blog/blogpost.leaf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Views/blog/blogpost.leaf b/Resources/Views/blog/blogpost.leaf index b71eab0..88ee54a 100644 --- a/Resources/Views/blog/blogpost.leaf +++ b/Resources/Views/blog/blogpost.leaf @@ -16,7 +16,7 @@ #if(post.last_edited_date_iso8601) { } - + #loop(post.tags, "tag") { } From 757ef15bde59a013c0e287fea62d41fe566930d8 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 17 May 2017 01:10:35 +0100 Subject: [PATCH 21/32] Package updates --- Package.pins | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Package.pins b/Package.pins index 71022e9..921989b 100644 --- a/Package.pins +++ b/Package.pins @@ -23,7 +23,7 @@ "package": "Bits", "reason": null, "repositoryURL": "https://github.com/vapor/bits.git", - "version": "1.0.0-beta.6" + "version": "1.0.0" }, { "package": "CTLS", @@ -41,7 +41,7 @@ "package": "Core", "reason": null, "repositoryURL": "https://github.com/vapor/core.git", - "version": "2.0.0-beta.9" + "version": "2.0.0" }, { "package": "Crypto", @@ -53,19 +53,19 @@ "package": "Debugging", "reason": null, "repositoryURL": "https://github.com/vapor/debugging.git", - "version": "1.0.0-beta.1" + "version": "1.0.0" }, { "package": "Engine", "reason": null, "repositoryURL": "https://github.com/vapor/engine.git", - "version": "2.0.0-beta.6" + "version": "2.0.0-beta.7" }, { "package": "Fluent", "reason": null, "repositoryURL": "https://github.com/vapor/fluent.git", - "version": "2.0.0-beta.27" + "version": "2.0.0-beta.28" }, { "package": "FluentProvider", @@ -83,7 +83,7 @@ "package": "Leaf", "reason": null, "repositoryURL": "https://github.com/vapor/leaf.git", - "version": "2.0.0-beta.7" + "version": "2.0.0-beta.8" }, { "package": "LeafMarkdown", @@ -173,7 +173,7 @@ "package": "Vapor", "reason": null, "repositoryURL": "https://github.com/vapor/vapor.git", - "version": "2.0.0-beta.25" + "version": "2.0.0-beta.26" }, { "package": "VaporSecurityHeaders", From ff5f1eac34dbdcd0af6ae21ebd3cc1b030643771 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 17 May 2017 01:24:26 +0100 Subject: [PATCH 22/32] Package updates --- Package.pins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.pins b/Package.pins index 921989b..a7d2f4a 100644 --- a/Package.pins +++ b/Package.pins @@ -143,7 +143,7 @@ "package": "SteamPress", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/SteamPress.git", - "version": "0.11.0-alpha.8" + "version": "0.11.0-alpha.9" }, { "package": "SwiftMarkdown", From e9c2fa59cf0526577e558e1d65e2d652383822e0 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 17 May 2017 02:02:12 +0100 Subject: [PATCH 23/32] Fix production config syntax errors --- Config/production/csp.json | 2 +- Config/production/disqus.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/production/csp.json b/Config/production/csp.json index ab12cb0..3d51ac1 100644 --- a/Config/production/csp.json +++ b/Config/production/csp.json @@ -1,3 +1,3 @@ { - "report-uri": $CSP_REPORT_URI + "report-uri": "$CSP_REPORT_URI" } diff --git a/Config/production/disqus.json b/Config/production/disqus.json index 8f9586f..0486f7c 100644 --- a/Config/production/disqus.json +++ b/Config/production/disqus.json @@ -1,3 +1,3 @@ { - "disqus.disqusName": $DISQUS_NAME + "disqus.disqusName": "$DISQUS_NAME" } From 057d92f02325b92e2f3695f33026f9bbcee83c18 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 17 May 2017 13:29:28 +0100 Subject: [PATCH 24/32] Fix Disqus configuration --- Config/production/disqus.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/production/disqus.json b/Config/production/disqus.json index 0486f7c..026b385 100644 --- a/Config/production/disqus.json +++ b/Config/production/disqus.json @@ -1,3 +1,3 @@ { - "disqus.disqusName": "$DISQUS_NAME" + "disqusName": "$DISQUS_NAME" } From 49043df20e3cffa80318ed0034085d9d5be3ed08 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 17 May 2017 15:05:50 +0100 Subject: [PATCH 25/32] Use custom sessions from SteamPress --- Config/droplet.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/droplet.json b/Config/droplet.json index 4e61cae..f8d10c4 100644 --- a/Config/droplet.json +++ b/Config/droplet.json @@ -11,7 +11,7 @@ "blog-error", "date", "file", - "sessions", + "steampress-sessions", "blog-persist" ], "commands": [ From 133bfaa0d6689060ef8b862f5a873aa2a2883a9e Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Fri, 19 May 2017 12:33:23 +0100 Subject: [PATCH 26/32] Use latest release --- Package.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Package.swift b/Package.swift index c9e75f1..f838374 100644 --- a/Package.swift +++ b/Package.swift @@ -3,10 +3,10 @@ import PackageDescription let package = Package( name: "SteamPressExample", dependencies: [ - .Package(url: "https://github.com/vapor/vapor.git", Version(2,0,0, prereleaseIdentifiers: ["beta"])), - .Package(url: "https://github.com/brokenhandsio/SteamPress.git", Version(0,11,0, prereleaseIdentifiers: ["alpha"])), - .Package(url: "https://github.com/brokenhandsio/VaporSecurityHeaders.git", Version(0,4,0, prereleaseIdentifiers: ["beta"])), - .Package(url: "https://github.com/vapor/leaf-provider.git", Version(1,0,0, prereleaseIdentifiers: ["beta"])) + .Package(url: "https://github.com/vapor/vapor.git", majorVersion: 2), + .Package(url: "https://github.com/brokenhandsio/SteamPress.git", Version(0,11,0, prereleaseIdentifiers: ["beta"])), + .Package(url: "https://github.com/brokenhandsio/VaporSecurityHeaders.git", majorVersion: 1), + .Package(url: "https://github.com/vapor/leaf-provider.git", majorVersion: 1) ], exclude: [ "Config", From f8c620534216b52328bd5acbe24071eaddbf1499 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Fri, 19 May 2017 21:33:31 +0100 Subject: [PATCH 27/32] Update SteamPress to fix login bug --- Package.pins | 68 ++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/Package.pins b/Package.pins index a7d2f4a..ee4aa10 100644 --- a/Package.pins +++ b/Package.pins @@ -5,19 +5,19 @@ "package": "Auth", "reason": null, "repositoryURL": "https://github.com/vapor/auth.git", - "version": "1.0.0-beta.2" + "version": "1.0.0" }, { "package": "AuthProvider", "reason": null, "repositoryURL": "https://github.com/vapor/auth-provider.git", - "version": "1.0.0-beta.5" + "version": "1.0.0" }, { "package": "BCrypt", "reason": null, "repositoryURL": "https://github.com/vapor/bcrypt.git", - "version": "1.0.0-beta.1" + "version": "1.0.0" }, { "package": "Bits", @@ -29,25 +29,25 @@ "package": "CTLS", "reason": null, "repositoryURL": "https://github.com/vapor/ctls.git", - "version": "1.0.0-beta.4" + "version": "1.0.0" }, { "package": "Console", "reason": null, "repositoryURL": "https://github.com/vapor/console.git", - "version": "2.0.0-beta.6" + "version": "2.0.0" }, { "package": "Core", "reason": null, "repositoryURL": "https://github.com/vapor/core.git", - "version": "2.0.0" + "version": "2.0.1" }, { "package": "Crypto", "reason": null, "repositoryURL": "https://github.com/vapor/crypto.git", - "version": "2.0.0-beta.1" + "version": "2.0.0" }, { "package": "Debugging", @@ -59,97 +59,91 @@ "package": "Engine", "reason": null, "repositoryURL": "https://github.com/vapor/engine.git", - "version": "2.0.0-beta.7" + "version": "2.0.0" }, { "package": "Fluent", "reason": null, "repositoryURL": "https://github.com/vapor/fluent.git", - "version": "2.0.0-beta.28" + "version": "2.0.0" }, { "package": "FluentProvider", "reason": null, "repositoryURL": "https://github.com/vapor/fluent-provider.git", - "version": "1.0.0-beta.15" + "version": "1.0.0" }, { "package": "JSON", "reason": null, "repositoryURL": "https://github.com/vapor/json.git", - "version": "2.0.0-beta.5" + "version": "2.0.0" }, { "package": "Leaf", "reason": null, "repositoryURL": "https://github.com/vapor/leaf.git", - "version": "2.0.0-beta.8" + "version": "2.0.0" }, { - "package": "LeafMarkdown", + "package": "LeafProvider", "reason": null, - "repositoryURL": "https://github.com/brokenhandsio/LeafMarkdown.git", - "version": "0.3.0-beta.5" + "repositoryURL": "https://github.com/vapor/leaf-provider.git", + "version": "1.0.0" }, { - "package": "LeafProvider", + "package": "MarkdownProvider", "reason": null, - "repositoryURL": "https://github.com/vapor/leaf-provider.git", - "version": "1.0.0-beta.4" + "repositoryURL": "https://github.com/vapor-community/markdown-provider.git", + "version": "1.0.0" }, { "package": "Multipart", "reason": null, "repositoryURL": "https://github.com/vapor/multipart.git", - "version": "2.0.0-beta.2" + "version": "2.0.0" }, { "package": "Node", "reason": null, "repositoryURL": "https://github.com/vapor/node.git", - "version": "2.0.0-beta.7" - }, - { - "package": "PathIndexable", - "reason": null, - "repositoryURL": "https://github.com/vapor/path-indexable.git", - "version": "2.0.0-beta.1" + "version": "2.0.0" }, { "package": "Random", "reason": null, "repositoryURL": "https://github.com/vapor/random.git", - "version": "1.0.0-beta.3" + "version": "1.0.0" }, { "package": "Routing", "reason": null, "repositoryURL": "https://github.com/vapor/routing.git", - "version": "2.0.0-beta.5" + "version": "2.0.0" }, { "package": "SQLite", "reason": null, "repositoryURL": "https://github.com/vapor/sqlite.git", - "version": "2.0.0-beta.1" + "version": "2.0.0" }, { "package": "Sockets", "reason": null, - "repositoryURL": "https://github.com/vapor/socks.git", - "version": "2.0.0-beta.6" + "repositoryURL": "https://github.com/vapor/sockets.git", + "version": "2.0.0" }, { "package": "SteamPress", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/SteamPress.git", - "version": "0.11.0-alpha.9" + "version": "0.11.0-beta.2" }, { "package": "SwiftMarkdown", "reason": null, - "repositoryURL": "https://github.com/brokenhandsio/SwiftMarkdown.git", - "version": "0.2.0" + "repositoryURL": "https://github.com/vapor-community/markdown.git", + "version": "0.3.0" }, { "package": "SwiftSoup", @@ -161,7 +155,7 @@ "package": "TLS", "reason": null, "repositoryURL": "https://github.com/vapor/tls.git", - "version": "2.0.0-beta.4" + "version": "2.0.0" }, { "package": "Validation", @@ -173,13 +167,13 @@ "package": "Vapor", "reason": null, "repositoryURL": "https://github.com/vapor/vapor.git", - "version": "2.0.0-beta.26" + "version": "2.0.1" }, { "package": "VaporSecurityHeaders", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/VaporSecurityHeaders.git", - "version": "0.4.0-beta.3" + "version": "1.0.0" }, { "package": "cmark", From 339a57e269f2fc1288f8dea78759c6b36230c50b Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Fri, 19 May 2017 21:42:34 +0100 Subject: [PATCH 28/32] Make images display a bit better and fix blockquote --- Public/static/css/style.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Public/static/css/style.css b/Public/static/css/style.css index e0a3fbb..2b41d07 100644 --- a/Public/static/css/style.css +++ b/Public/static/css/style.css @@ -42,6 +42,14 @@ h1.lead-title-blog { margin-left: auto; margin-right: auto; display: block; + max-width: 100%; +} + +.post-contents blockquote { + background: #f7f7f7; + padding: .5rem 1rem; + padding-top: 1rem; + margin-bottom: 1rem; } .form-signin { From 2a16718c17b8468b5689fd1ba12c22d360157fe2 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Fri, 19 May 2017 21:44:38 +0100 Subject: [PATCH 29/32] Fix overflow on mobile --- Public/static/css/style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Public/static/css/style.css b/Public/static/css/style.css index 2b41d07..bb6ccae 100644 --- a/Public/static/css/style.css +++ b/Public/static/css/style.css @@ -45,6 +45,11 @@ h1.lead-title-blog { max-width: 100%; } +.post-contents { + overflow-wrap: break-word; + word-wrap: break-word; +} + .post-contents blockquote { background: #f7f7f7; padding: .5rem 1rem; From 4a3fd93d057df0f16d034faaf9803a03c8cdffee Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Tue, 23 May 2017 21:15:01 +0100 Subject: [PATCH 30/32] Update README to reflect to website --- Package.pins | 12 ++++++------ README.md | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Package.pins b/Package.pins index ee4aa10..51c2d05 100644 --- a/Package.pins +++ b/Package.pins @@ -11,7 +11,7 @@ "package": "AuthProvider", "reason": null, "repositoryURL": "https://github.com/vapor/auth-provider.git", - "version": "1.0.0" + "version": "1.0.1" }, { "package": "BCrypt", @@ -65,7 +65,7 @@ "package": "Fluent", "reason": null, "repositoryURL": "https://github.com/vapor/fluent.git", - "version": "2.0.0" + "version": "2.0.1" }, { "package": "FluentProvider", @@ -77,7 +77,7 @@ "package": "JSON", "reason": null, "repositoryURL": "https://github.com/vapor/json.git", - "version": "2.0.0" + "version": "2.0.1" }, { "package": "Leaf", @@ -107,7 +107,7 @@ "package": "Node", "reason": null, "repositoryURL": "https://github.com/vapor/node.git", - "version": "2.0.0" + "version": "2.0.1" }, { "package": "Random", @@ -131,7 +131,7 @@ "package": "Sockets", "reason": null, "repositoryURL": "https://github.com/vapor/sockets.git", - "version": "2.0.0" + "version": "2.0.1" }, { "package": "SteamPress", @@ -167,7 +167,7 @@ "package": "Vapor", "reason": null, "repositoryURL": "https://github.com/vapor/vapor.git", - "version": "2.0.1" + "version": "2.0.2" }, { "package": "VaporSecurityHeaders", diff --git a/README.md b/README.md index 2685fe1..d916855 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # SteamPress Example -This is an example site for using [SteamPress](https://github.com/brokenhandsio/SteamPress) with your Vapor website. You can also just use it as your blog! This example site uses Bootstrap 4 for styling so should be fairly easy to make it look how you want. It also uses Markdown to render the blog posts, and has Syntax highlighting for code (obviously!). This site can be viewed at https://steampress-example.herokuapp.com/. +This is an example site for using [SteamPress](https://github.com/brokenhandsio/SteamPress) with your Vapor website. You can also just use it as your blog! This example site uses Bootstrap 4 for styling so should be fairly easy to make it look how you want. It also uses Markdown to render the blog posts, and has Syntax highlighting for code (obviously!). This site can be viewed at https://www.steampress.io/. This site also provides a good example for all the Leaf files you will need, and the parameters they are given, as well as what you need to send to SteamPress to be create users and posts etc. From 18bffd05420176a3c8a02bf6198201855c9be2a3 Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 24 May 2017 13:39:02 +0100 Subject: [PATCH 31/32] Use SteamPress release --- Package.pins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.pins b/Package.pins index 51c2d05..24949ff 100644 --- a/Package.pins +++ b/Package.pins @@ -137,7 +137,7 @@ "package": "SteamPress", "reason": null, "repositoryURL": "https://github.com/brokenhandsio/SteamPress.git", - "version": "0.11.0-beta.2" + "version": "0.11.0" }, { "package": "SwiftMarkdown", From c5139e692d64c1102ad329fef2158682615bf3af Mon Sep 17 00:00:00 2001 From: Tim <0xtimc@gmail.com> Date: Wed, 24 May 2017 13:45:16 +0100 Subject: [PATCH 32/32] Update Package.swift so we use releases of SteamPress --- Package.pins | 2 +- Package.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Package.pins b/Package.pins index 24949ff..b61b052 100644 --- a/Package.pins +++ b/Package.pins @@ -11,7 +11,7 @@ "package": "AuthProvider", "reason": null, "repositoryURL": "https://github.com/vapor/auth-provider.git", - "version": "1.0.1" + "version": "1.0.2" }, { "package": "BCrypt", diff --git a/Package.swift b/Package.swift index f838374..962b9a6 100644 --- a/Package.swift +++ b/Package.swift @@ -4,7 +4,7 @@ let package = Package( name: "SteamPressExample", dependencies: [ .Package(url: "https://github.com/vapor/vapor.git", majorVersion: 2), - .Package(url: "https://github.com/brokenhandsio/SteamPress.git", Version(0,11,0, prereleaseIdentifiers: ["beta"])), + .Package(url: "https://github.com/brokenhandsio/SteamPress.git", majorVersion: 0), .Package(url: "https://github.com/brokenhandsio/VaporSecurityHeaders.git", majorVersion: 1), .Package(url: "https://github.com/vapor/leaf-provider.git", majorVersion: 1) ],