Skip to content

Instantly share code, notes, and snippets.

@ditansu
Created February 3, 2018 16:12
Show Gist options
  • Save ditansu/4c14211b2e97894d3baf8250d36cb97a to your computer and use it in GitHub Desktop.
Save ditansu/4c14211b2e97894d3baf8250d36cb97a to your computer and use it in GitHub Desktop.
Generation token moved into Session.swift
import Vapor
import FluentProvider
import Crypto
import Foundation
// sourcery: AutoModelGeneratable
// sourcery: fromJSON, toJSON, Preparation, Timestampable, Updateable
final class Session: Model {
let storage = Storage()
// sourcery: unique = true
var userId: Identifier
var token: String
var actual: Bool
init(userId: Identifier,
token: String,
actual: Bool = true) {
self.userId = userId
self.token = token
self.actual = actual
}
convenience init (user: User, actual: Bool = true) throws {
self.init(
userId: try user.assertExists(),
token: try Session.generateToken(),
actual: actual
)
}
// sourcery:inline:auto:Session.AutoModelGeneratable
init(row: Row) throws {
userId = try row.get(Keys.userId)
token = try row.get(Keys.token)
actual = try row.get(Keys.actual)
}
func makeRow() throws -> Row {
var row = Row()
try row.set(Keys.userId, userId)
try row.set(Keys.token, token)
try row.set(Keys.actual, actual)
return row
}
// sourcery:end
}
extension Session {
static func find(by token: String) throws -> Session? {
return try Session.makeQuery().filter(Keys.token, token).first()
}
var user: User? {
return try? parent(id: userId).get()!
}
static func find(by user: User) throws -> Session? {
guard let userId = user.id else {
throw Abort(.internalServerError, reason: "User not found")
}
return try Session.makeQuery().filter(Keys.userId, userId).first()
}
static func generateToken() throws -> String {
let random = try Crypto.Random.bytes(count: 16)
return random.base64Encoded.makeString()
}
@discardableResult
static func updateToken(for user: User) throws -> Session {
guard let session = try Session.find(by: user), let updatedAt = session.updatedAt else {
throw Abort.serverError
}
if let referenceDate = Calendar.current.date(byAdding: .month, value: 1, to: updatedAt),
referenceDate < Date() {
session.token = try generateToken()
try session.save()
}
return session
}
}
import Vapor
import FluentProvider
// sourcery: AutoModelGeneratable
// sourcery: fromJSON, toJSON, Preparation, Updateable, ResponseRepresentable, Timestampable
final class User: Model {
let storage = Storage()
var name: String
var lastname: String
var company: String
var position: String
var photo: String
var email: String
var phone: String
init(name: String,
lastname: String,
company: String = "",
position: String = "",
photo: String = "",
email: String = "",
phone: String = "") {
self.name = name
self.lastname = lastname
self.company = company
self.position = position
self.photo = photo
self.email = email
self.phone = phone
}
// sourcery:inline:auto:User.AutoModelGeneratable
init(row: Row) throws {
name = try row.get(Keys.name)
lastname = try row.get(Keys.lastname)
company = try row.get(Keys.company)
position = try row.get(Keys.position)
photo = try row.get(Keys.photo)
email = try row.get(Keys.email)
phone = try row.get(Keys.phone)
}
func makeRow() throws -> Row {
var row = Row()
try row.set(Keys.name, name)
try row.set(Keys.lastname, lastname)
try row.set(Keys.company, company)
try row.set(Keys.position, position)
try row.set(Keys.photo, photo)
try row.set(Keys.email, email)
try row.set(Keys.phone, phone)
return row
}
// sourcery:end
}
// MARK: Relations
extension User {
var clients: Children<User, Client> {
return children()
}
private var sessions: Children<User, Session> {
return children()
}
func session() throws -> Session? {
return try sessions.first()
}
func didCreate() {
do {
let session = try Session(user: self)
try session.save()
} catch {
try? self.delete()
}
}
func updateSessionToken() throws {
try Session.updateToken(for: self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment