| @@ -54,6 +54,24 @@ | |||
| "version" : "2.8.0" | |||
| } | |||
| }, | |||
| { | |||
| "identity" : "jwt", | |||
| "kind" : "remoteSourceControl", | |||
| "location" : "https://github.com/vapor/jwt.git", | |||
| "state" : { | |||
| "revision" : "d65f32bfd08fae5910d603028be5dec4f35b3482", | |||
| "version" : "4.2.2" | |||
| } | |||
| }, | |||
| { | |||
| "identity" : "jwt-kit", | |||
| "kind" : "remoteSourceControl", | |||
| "location" : "https://github.com/vapor/jwt-kit.git", | |||
| "state" : { | |||
| "revision" : "e05513b5aec24f88012b6e3034115b6bc915356a", | |||
| "version" : "4.13.2" | |||
| } | |||
| }, | |||
| { | |||
| "identity" : "multipart-kit", | |||
| "kind" : "remoteSourceControl", | |||
| @@ -13,6 +13,7 @@ let package = Package( | |||
| .package(url: "https://github.com/vapor/fluent.git", from: "4.9.0"), | |||
| // 🐘 Fluent driver for Postgres. | |||
| .package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.8.0"), | |||
| .package(url: "https://github.com/vapor/jwt.git", from: "4.0.0-rc.1"), | |||
| ], | |||
| targets: [ | |||
| .executableTarget( | |||
| @@ -21,6 +22,7 @@ let package = Package( | |||
| .product(name: "Fluent", package: "fluent"), | |||
| .product(name: "FluentPostgresDriver", package: "fluent-postgres-driver"), | |||
| .product(name: "Vapor", package: "vapor"), | |||
| .product(name: "JWT", package: "jwt"), | |||
| ], | |||
| swiftSettings: swiftSettings | |||
| ), | |||
| @@ -23,9 +23,10 @@ struct cntrlAssociate: RouteCollection { | |||
| @Sendable | |||
| func index(req: Request) async throws -> Response { | |||
| guard let obj = try? await mdlAssociate.ObjQuery(req: req).all() else { | |||
| throw Abort(.badGateway, reason: "Something went wrong with this api.") | |||
| } | |||
| let obj = try await mdlAssociate.ObjQuery(req: req).all() | |||
| // guard let obj = try? await mdlAssociate.ObjQuery(req: req).all() else { | |||
| // throw Abort(.badGateway, reason: "Something went wrong with this api.") | |||
| // } | |||
| guard let response = try? await obj.encodeResponse(status: .ok, for: req) else{ | |||
| throw Abort(.noContent, reason: "Something went wrong decoding data. Array could not be shown.") | |||
| } | |||
| @@ -5,4 +5,15 @@ | |||
| // Created by Michiel Carman on 4/13/24. | |||
| // | |||
| import Foundation | |||
| import Fluent | |||
| import Vapor | |||
| struct cntrlJWT: RouteCollection{ | |||
| func boot(routes: Vapor.RoutesBuilder) throws { | |||
| let rts = routes.grouped("jwt") | |||
| rts.get{req in | |||
| try req.jwt.sign(mdlJWT(result: "test"), kid: .private) | |||
| } | |||
| } | |||
| } | |||
| @@ -19,6 +19,7 @@ public func doMigrations(_ app: Application) async throws{ | |||
| app.migrations.add(mdlDocument.Create()) | |||
| app.migrations.add(mdlXAssocDept.Create()) | |||
| app.migrations.add(mdlXDocDept.Create()) | |||
| app.migrations.add(mdlDocument.tmpField()) | |||
| try await app.autoMigrate() | |||
| } | |||
| @@ -17,7 +17,7 @@ final class mdlDepartment: Model, Content { | |||
| @ID(custom: "id", generatedBy: .database) var id: Int? | |||
| @Field(key: "name") var name: String? | |||
| @OptionalParent(key: "parentId") var parent: mdlDepartment? | |||
| @OptionalParent(key: "departmentId") var parent: mdlDepartment? | |||
| @Children(for: \.$parent) var subdepartments: [mdlDepartment] | |||
| @Siblings(through: mdlXAssocDept.self, from: \.$department, to: \.$associate) var associates: [mdlAssociate] | |||
| @@ -18,7 +18,7 @@ final class mdlDocument: Model, Content { | |||
| @Field(key: "name") var name: String? | |||
| @Field(key: "number") var number: String? | |||
| @Parent(key: "docTypeId") var doctype: mdlDocType | |||
| @OptionalParent(key: "docTypeId") var doctype: mdlDocType? | |||
| @Parent(key: "departmentId") var department: mdlDepartment | |||
| @OptionalParent(key: "parentId") var parent: mdlDocument? | |||
| @Children(for: \.$parent) var subsequent: [mdlDocument] | |||
| @@ -33,7 +33,7 @@ final class mdlDocument: Model, Content { | |||
| init(id: Int? = nil, | |||
| name: String? = nil, | |||
| number: String? = nil, | |||
| doctypeid: Int, | |||
| doctypeid: Int? = nil, | |||
| departmentid: Int, | |||
| parentid: Int? = nil, | |||
| createuserid: Int? = nil, | |||
| @@ -42,7 +42,7 @@ final class mdlDocument: Model, Content { | |||
| self.id = id | |||
| self.name = name | |||
| self.number = number | |||
| self.$doctype.$id.value = doctypeid | |||
| if(doctypeid != nil) { self.$doctype.$id.value = doctypeid } | |||
| self.$department.$id.value = departmentid | |||
| if(parentid != nil) { self.$parent.$id.value = parentid } | |||
| self.createuserid = createuserid | |||
| @@ -70,6 +70,19 @@ extension mdlDocument{ | |||
| try await database.schema("document").delete() | |||
| } | |||
| } | |||
| struct tmpField: AsyncMigration { | |||
| func prepare(on database: Database) async throws { | |||
| try await database.schema("document") | |||
| .field("dept", .string) | |||
| .update() | |||
| } | |||
| func revert(on database: Database) async throws { | |||
| try await database.schema("document") | |||
| .deleteField("dept") | |||
| .update() | |||
| } | |||
| } | |||
| public static func ObjQuery(req: Request) async throws -> QueryBuilder<mdlDocument>{ | |||
| let query = mdlDocument.query(on: req.db) | |||
| @@ -5,4 +5,10 @@ | |||
| // Created by Michiel Carman on 4/13/24. | |||
| // | |||
| import Foundation | |||
| import Vapor | |||
| import JWT | |||
| struct mdlJWT: JWTPayload{ | |||
| var result: String | |||
| func verify(using signer: JWTKit.JWTSigner) {} | |||
| } | |||
| @@ -2,9 +2,29 @@ import NIOSSL | |||
| import Fluent | |||
| import FluentPostgresDriver | |||
| import Vapor | |||
| import JWT | |||
| extension String { | |||
| var bytes: [UInt8] { .init(self.utf8) } | |||
| } | |||
| extension JWKIdentifier { | |||
| static let `public` = JWKIdentifier(string: "public") | |||
| static let `private` = JWKIdentifier(string: "private") | |||
| } | |||
| // configures your application | |||
| public func configure(_ app: Application) async throws { | |||
| let privateKey = try String(contentsOfFile: app.directory.workingDirectory + "jwtRS256.key") | |||
| let privateSigner = try JWTSigner.rs256(key: .private(pem: privateKey.bytes)) | |||
| let publicKey = try String(contentsOfFile: app.directory.workingDirectory + "jwtRS256.key.pub") | |||
| let publicSigner = try JWTSigner.rs256(key: .public(pem: publicKey.bytes)) | |||
| app.jwt.signers.use(privateSigner, kid: .private) | |||
| app.jwt.signers.use(publicSigner, kid: .public, isDefault: true) | |||
| app.middleware.use(CORSMiddleware()) | |||
| let corsConfiguration = CORSMiddleware.Configuration( | |||
| allowedOrigin: .all, | |||
| @@ -11,4 +11,6 @@ func routes(_ app: Application) throws { | |||
| baseApp.get { req async in | |||
| "Training Services Version 1.0" | |||
| } | |||
| try baseApp.register(collection: cntrlAssociate()) | |||
| try baseApp.register(collection: cntrlDepartment()) | |||
| } | |||
| @@ -0,0 +1,54 @@ | |||
| -----BEGIN RSA PRIVATE KEY----- | |||
| Proc-Type: 4,ENCRYPTED | |||
| DEK-Info: AES-128-CBC,8302B108E3C2CB279C4FF6742ECEC521 | |||
| QGPy1l4ZF+dkQ5THYszj6lnAzUKd7hv6+XituyCwJa1pz5E0h3Ux10/vG8jdbVss | |||
| 6LuM0uUaq61ytJiSrI8bZ2i0xXN5MEqbViyoZOapzeRAbqbNBKY12oDUNI3WcK+I | |||
| aJGwVUTvLjRyO4YdRTPlIsYJ2EAi5O8+9nAqy8ArB5Bqkjoemh5lgODDqAHuMbE9 | |||
| v9D3n/Dagsc78WN8MyUmetG18qMAtvVSziGJVwjdIBUberlHSPAJIXBW76pF6O/z | |||
| lj8NP+L/MysXg8TnIhZnqg7CkEAKYLlFYGzEOasxYW7bOEMMP6kixIX0INLpoR0Y | |||
| lzA9KO7dLo9I4FS+f1tbJHvz14MAF4SvLpvrgbMn0wOhns9SuIWuw1eOCRCH2Wpx | |||
| GiXNvwn+2DVtfjORODjBOpLpQAlhJt+02N0hjLoTPUmTikJSj4yFniPYnye+2vGq | |||
| 91+/51EZGHJmcbDUfyasY5BRBckDe/Q5/VOBusyFuVU4beGWF+HY4Va309ZrS/sw | |||
| ANXpYyTIOtqJH+tpNZQEq0XnSdFMK/QQOe1GPRULJRl2MJhuG0ODacH3yWqUeLj9 | |||
| DfKclXGtMO76i0zkrb22c4GDHPAZKWa4vD8M+vctVRKYtUTLhykZzbgmExUdtcrn | |||
| 7WyG9A65vtISvJME0NzagzcxaTNHHPDtWTNw9R7MJxvshyZ2TVsDXWhyY0V+HJLG | |||
| Z1C7bUhaThCZ7f5kYpe9TCNNpEFFdfrQCcYjKYvD8jI2KCvvxa1I4BWaw24F1cDc | |||
| JdAQLfaw819G4+AV0Q76suQQAdRFhRuVe3Si1j9ErG8rm7wsF6WmLDOFGfvzpZH0 | |||
| SvyDeBgVHaul6tQqA9Q3nKfrXgpvrkWuMoPqnPdlLwUmWGDdJM0CJAH1726ZT/pG | |||
| Bp3jvYs3pHoXuClJt0GjxJ49trl+oZrZUGMJnARH+O//3geHBt0uMk6QNe9TpKX8 | |||
| PnNKUY+jcSyK9BSAt6J01dVKcg4AvCvpo5QymyRLp9wyxc/jlkRiSsPsg/qrlA9g | |||
| OaFdl+oWTCCYdXsot1tTRZj5SpJzT4PE/XX1KbanOdHfCNQ4SfgG6ejgdxcT9g4M | |||
| iaVrq0hnQdmZq3tytwi3KiyPWYU1sdv0UxSgGC45+D1sqGyhjM7hnv6zGJGEYH08 | |||
| zOt7oGqQMYGY7qrXL/U2SzkjAYURNQiwD5kZLPh2adaJsD4SEv3Q22l5TpWb+TyT | |||
| 7U9yiXy45xrANk6TpBxc9+hTjyAqEEBEXUbXavMDcDD7GD/qj9qHj7jH78TBNXQd | |||
| CSYdacyBRZy6+EIbvYY+APBlq7eICrzHg7OYp9n/CeJeXVz9A8KQ9txBroQ/7ZLJ | |||
| 15BX+z09a09J9L6UpSu2XzcSQbwUq53NJMZJQsfxPU7vrFQDHyNSTPOTvcX7xN9k | |||
| bzmZM5xxN4jni05jVtj/hqq6SPapi7vhrBAMaA6LlYVmZDx+sMoyS0cQf6hrQpxq | |||
| EjpkEaE6HgY4zCQwEPmFfPPpPtPaNSAQZqzL6MlFGYgMJjvulk1S4raPoNC/ZFnH | |||
| wr16ebsZrMiVJxPXh4aDcsh3b/7XsTm+WRoyukxuLsFuJffOeTj3nlcG7k+wV8mp | |||
| duzb6oHDC1Uw7mKlFvNorHz2e12+Cr+SsX+tWtXSIfVAbMxAQ4f1YyfUvMFX+MJt | |||
| xikb85ITIjGmsz4qgob5WoMa8FU3/lwjKHW1swpnAijtW9AToS5rnhhjAmTxAF/8 | |||
| wlOn0EbNV3Dl6F9kSrHK1HrFAxlh2RD61PmXvBXSdyIk2NjTNE/auKzUQ8eWUmut | |||
| xtHUcS0dHJKd7BAJSVMqDsxPcj8sQa2fww/ZETGiW63PtXv9UhR3d19Ic6gGkUGI | |||
| xNohGxJuvYWGUINpKUmjCUsHXGFvUjOaoZSv3iJ0DdVe72ZLcv0X3nyl24LTi5Fj | |||
| aa5A7afDPkvY95bDoa0vPLqZIeRA5iyAiKoPaj11owUub0E13OgTxdGcgZO68Cgu | |||
| gK+lkFByKDVCYZ2SMvsVhuiDvBPjtZ3zkZ7UQ0P2KffWG123W4xYbc+tCM4LO/AV | |||
| 5OhmCitlyt8yxEkpk6B6L4ggqIs6/nVBK0yNa40mgoj6G0sVvvvA9a9YsoY7w2PF | |||
| iVKj/GewnMqU/oyQajwtQWyULpyJ44AtBTpPsmY5uebCcEq1zRjevEDADHl/PL4U | |||
| 3+5/MrpX4qiqMCGKI0niwgtDQcUzuiUQfN2gbHwKjo6cF9GA6/EfIYIfBwTcP0Vh | |||
| iqwI3JD3vHpKxprYhs12+UCX9ioDBTiP6uymELAjQBKkkLuDj7YLN7RK4JizYlAn | |||
| /6D4Nmh7UIFRxaB6EmAV8z8GxQltwWqv0jnfelTU5leIV8tBqirzgDBvqdCZIjJ3 | |||
| kWiGUyVRPT+GmGq+9ostrGPzhQDSI/k0PuKZS5GCOXPR5boT5bDeXNdoeIFY/eq6 | |||
| nMVMbcP2lRxKuQuBS+Nr90T32rv755vzUMBwNossedszhkXRgUvcfcqUyDJ12+qz | |||
| qbB7RSdhNJVgwVBsuOl74Y1ERawBHBu0YiCD3OpDlNsdLmdG+2yi63z7cxPSmA+c | |||
| NUcMa3NOrUIYn4QzgqCvuldkAERzltRemRlgu5JdqF8HbG4q8bZHYrC0QiG6FAhm | |||
| qBYmaaWDWVwMpJ6pGe3/1zGWVUvSfcg66Wa7U2MsKtOx0zpFbZ8bQzosTTXmOiH0 | |||
| KSHE/HtmZAaDpU46S6FNIybuVxAIz9XTAkFoLtcpQdq5AIYHpnZjVtEfaP+Vux5R | |||
| 0cQfhBtxMYZamlcCzrHLHyuhB3uPif0yuAlXk1+Lkx8mBllJ+fpl82J9x9C9HbxV | |||
| QzEUB4ONApiVWaQRrMWkUjfYv5W4VcOpVBZAe1W3TpjM7dBKVm4KZxtjJx1Ys85v | |||
| qXoqWI9eRYgdc+uhDF61WNT7MpykU4jWINr6OJAUJ19XXYRqvf4B7ivUt22XZdsS | |||
| UgNFd2Q9LHR2Fh/kOV6uQmpgYLTE1mvZgvdv+S1ObrXHFDRffzXkmMjQDclWNkWC | |||
| WxtMBkHtC2n0INwsq52mKR+FYB0E+IygflJafwhOzf/XfK02iZDpk80dg0l+DxVb | |||
| yiQwmVtSHj9Y7cdUVB1l6sFZCx4pc3z3RQjyOesxAAbx9joRz3HBvqSVq4JY7kuv | |||
| -----END RSA PRIVATE KEY----- | |||
| @@ -0,0 +1,14 @@ | |||
| -----BEGIN PUBLIC KEY----- | |||
| MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsJ60y2SCZXKsXh+pGSrc | |||
| z/wXwt4O39jpBnTh9irvDg4PQD9z+FLp0Iy0s5tq7VNXr8+77zOVgiiIIKWOIukC | |||
| hWztueEfM5tQ/9SEblHVN/s1ZyT7ESY+pZJY0lTiPVQ49nEmigNGXA7HCt+pXU0k | |||
| /PhSLjX1MJ5MoexZ+8WvSs9VDOnJxfwfw5qU+ATAJHm64ijD0hPOcErlBppZZuo/ | |||
| 7Y9RrNF1BXQxtqSIzZI4U+ndCXcjYB2w7JcfwrpQJji+EBbO9rO0OYLdP0LTAVWW | |||
| uDPt4JRA72sbYjBvvBejZcK5ssKO2RNi8xfI3bnXzyhIHdjlDhVs6q6ukr7LSLr6 | |||
| rFMvyedz28gfMf5Bs7MlzUi9itLIGtpIPjXAqDMa49CHJtZj59yXBl9deO+yv8AU | |||
| 75MpnlnjaQkns2V76zVyX/TcLunZd3jsLs6KWr4Kw6nUTsnfRxPgYYL2uSZ9wrZ/ | |||
| YhzJjx8tevzn4dC+JDEKP2iVZ9P7wUOfZsVVj1ICFkDt1yM4Wlh5oBtqdZZR/HJc | |||
| XgzAxUNMX9dkJUM7xzDA6Dc9UchvdHw+vYne5ROoepZHegmZiLveUET321RHsaEh | |||
| Mmoct4xmgVkGrhakQLPTAjDL1Vw3qHUr8nObF5rxTikR5SrhBX00cjRNcheyLd3u | |||
| O/pxZKD+UMAwwrmVAyFkTj8CAwEAAQ== | |||
| -----END PUBLIC KEY----- | |||