| @@ -54,6 +54,24 @@ | |||||
| "version" : "2.8.0" | "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", | "identity" : "multipart-kit", | ||||
| "kind" : "remoteSourceControl", | "kind" : "remoteSourceControl", | ||||
| @@ -13,6 +13,7 @@ let package = Package( | |||||
| .package(url: "https://github.com/vapor/fluent.git", from: "4.9.0"), | .package(url: "https://github.com/vapor/fluent.git", from: "4.9.0"), | ||||
| // 🐘 Fluent driver for Postgres. | // 🐘 Fluent driver for Postgres. | ||||
| .package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.8.0"), | .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: [ | targets: [ | ||||
| .executableTarget( | .executableTarget( | ||||
| @@ -21,6 +22,7 @@ let package = Package( | |||||
| .product(name: "Fluent", package: "fluent"), | .product(name: "Fluent", package: "fluent"), | ||||
| .product(name: "FluentPostgresDriver", package: "fluent-postgres-driver"), | .product(name: "FluentPostgresDriver", package: "fluent-postgres-driver"), | ||||
| .product(name: "Vapor", package: "vapor"), | .product(name: "Vapor", package: "vapor"), | ||||
| .product(name: "JWT", package: "jwt"), | |||||
| ], | ], | ||||
| swiftSettings: swiftSettings | swiftSettings: swiftSettings | ||||
| ), | ), | ||||
| @@ -23,9 +23,10 @@ struct cntrlAssociate: RouteCollection { | |||||
| @Sendable | @Sendable | ||||
| func index(req: Request) async throws -> Response { | 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{ | 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.") | 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. | // 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(mdlDocument.Create()) | ||||
| app.migrations.add(mdlXAssocDept.Create()) | app.migrations.add(mdlXAssocDept.Create()) | ||||
| app.migrations.add(mdlXDocDept.Create()) | app.migrations.add(mdlXDocDept.Create()) | ||||
| app.migrations.add(mdlDocument.tmpField()) | |||||
| try await app.autoMigrate() | try await app.autoMigrate() | ||||
| } | } | ||||
| @@ -17,7 +17,7 @@ final class mdlDepartment: Model, Content { | |||||
| @ID(custom: "id", generatedBy: .database) var id: Int? | @ID(custom: "id", generatedBy: .database) var id: Int? | ||||
| @Field(key: "name") var name: String? | @Field(key: "name") var name: String? | ||||
| @OptionalParent(key: "parentId") var parent: mdlDepartment? | |||||
| @OptionalParent(key: "departmentId") var parent: mdlDepartment? | |||||
| @Children(for: \.$parent) var subdepartments: [mdlDepartment] | @Children(for: \.$parent) var subdepartments: [mdlDepartment] | ||||
| @Siblings(through: mdlXAssocDept.self, from: \.$department, to: \.$associate) var associates: [mdlAssociate] | @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: "name") var name: String? | ||||
| @Field(key: "number") var number: 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 | @Parent(key: "departmentId") var department: mdlDepartment | ||||
| @OptionalParent(key: "parentId") var parent: mdlDocument? | @OptionalParent(key: "parentId") var parent: mdlDocument? | ||||
| @Children(for: \.$parent) var subsequent: [mdlDocument] | @Children(for: \.$parent) var subsequent: [mdlDocument] | ||||
| @@ -33,7 +33,7 @@ final class mdlDocument: Model, Content { | |||||
| init(id: Int? = nil, | init(id: Int? = nil, | ||||
| name: String? = nil, | name: String? = nil, | ||||
| number: String? = nil, | number: String? = nil, | ||||
| doctypeid: Int, | |||||
| doctypeid: Int? = nil, | |||||
| departmentid: Int, | departmentid: Int, | ||||
| parentid: Int? = nil, | parentid: Int? = nil, | ||||
| createuserid: Int? = nil, | createuserid: Int? = nil, | ||||
| @@ -42,7 +42,7 @@ final class mdlDocument: Model, Content { | |||||
| self.id = id | self.id = id | ||||
| self.name = name | self.name = name | ||||
| self.number = number | self.number = number | ||||
| self.$doctype.$id.value = doctypeid | |||||
| if(doctypeid != nil) { self.$doctype.$id.value = doctypeid } | |||||
| self.$department.$id.value = departmentid | self.$department.$id.value = departmentid | ||||
| if(parentid != nil) { self.$parent.$id.value = parentid } | if(parentid != nil) { self.$parent.$id.value = parentid } | ||||
| self.createuserid = createuserid | self.createuserid = createuserid | ||||
| @@ -70,6 +70,19 @@ extension mdlDocument{ | |||||
| try await database.schema("document").delete() | 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>{ | public static func ObjQuery(req: Request) async throws -> QueryBuilder<mdlDocument>{ | ||||
| let query = mdlDocument.query(on: req.db) | let query = mdlDocument.query(on: req.db) | ||||
| @@ -5,4 +5,10 @@ | |||||
| // Created by Michiel Carman on 4/13/24. | // 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 Fluent | ||||
| import FluentPostgresDriver | import FluentPostgresDriver | ||||
| import Vapor | 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 | // configures your application | ||||
| public func configure(_ app: Application) async throws { | 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()) | app.middleware.use(CORSMiddleware()) | ||||
| let corsConfiguration = CORSMiddleware.Configuration( | let corsConfiguration = CORSMiddleware.Configuration( | ||||
| allowedOrigin: .all, | allowedOrigin: .all, | ||||
| @@ -11,4 +11,6 @@ func routes(_ app: Application) throws { | |||||
| baseApp.get { req async in | baseApp.get { req async in | ||||
| "Training Services Version 1.0" | "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 | |||||
| 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 | |||||
| -----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----- | |||||