Move sessions to db table instead of JWTs
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import Vapor
|
||||
import Fluent
|
||||
import SwiftMsgpack
|
||||
import JWT
|
||||
|
||||
@@ -13,11 +14,24 @@ struct ToolController: RouteCollection {
|
||||
func signup(req: Request) async throws -> Response {
|
||||
let body = try req.content.decode(SignupReq.self, using: MsgPackDecoder())
|
||||
|
||||
let session = try await req.jwt.verify(body.access_token, as: SessionPayload.self)
|
||||
guard session.type == SessionType.ZAT.rawValue else {
|
||||
guard
|
||||
let session = try await Session.query(on: req.db).filter(\.$id == body.access_token).first(),
|
||||
session.type == SessionType.ZAT
|
||||
else {
|
||||
throw Abort(.forbidden, reason: "Invalid access token")
|
||||
}
|
||||
let accountId = session.$account.id
|
||||
|
||||
if let player = try await Player.query(on: req.db).filter(\.$account.$id == accountId).first() {
|
||||
|
||||
} else {
|
||||
guard let account = try await Account.query(on: req.db).filter(\.$id == accountId).first() else {
|
||||
throw Abort(.forbidden, reason: "Account ID does not exist")
|
||||
}
|
||||
// Create new Player
|
||||
let player = try Player.createDefault(account: account)
|
||||
try await player.save(on: req.db)
|
||||
}
|
||||
|
||||
throw Abort(.notImplemented)
|
||||
}
|
||||
|
@@ -61,12 +61,24 @@ struct AuthController: RouteCollection {
|
||||
let idpId = body.whiteKey
|
||||
var account: Account? = nil
|
||||
|
||||
if let rawAccountId = req.headers["playerId"].first, let accountId = Int(rawAccountId) {
|
||||
if let existingAccount = try await Account.query(on: req.db).filter(\.$id == accountId).first() {
|
||||
account = existingAccount
|
||||
}
|
||||
if
|
||||
let rawAccountId = req.headers["playerId"].first,
|
||||
let accountId = Int(rawAccountId),
|
||||
let existingAccount = try await Account.query(on: req.db).filter(\.$id == accountId).first()
|
||||
{
|
||||
account = existingAccount
|
||||
// Delete old sessions
|
||||
try await Session.query(on: req.db)
|
||||
.filter(\.$account.$id == existingAccount.requireID())
|
||||
.filter(\.$type ~~ [.ZAT, .ZRT])
|
||||
.delete()
|
||||
} else if let existingAccount = try await Account.query(on: req.db).filter(\.$idpId == idpId).first() {
|
||||
account = existingAccount
|
||||
// Delete old sessions
|
||||
try await Session.query(on: req.db)
|
||||
.filter(\.$account.$id == existingAccount.requireID())
|
||||
.filter(\.$type ~~ [.ZAT, .ZRT])
|
||||
.delete()
|
||||
} else {
|
||||
account = Account(appId: body.appId, idpAlias: idpAlias, idpCode: "zd3", idpId: idpId, status: "normal")
|
||||
try await account!.create(on: req.db)
|
||||
@@ -75,6 +87,7 @@ struct AuthController: RouteCollection {
|
||||
guard let account = account else {
|
||||
throw Abort(.badRequest)
|
||||
}
|
||||
print("got here")
|
||||
|
||||
if account.idpAlias != idpAlias {
|
||||
account.idpAlias = idpAlias
|
||||
@@ -84,11 +97,13 @@ struct AuthController: RouteCollection {
|
||||
let zatExpiry = Date.now.advanced(by: 43200)
|
||||
let zrtExpiry = Date.now.advanced(by: 2592000)
|
||||
|
||||
let zatTokenJWT = generateToken(accountId: try account.requireID(), expires: zatExpiry, type: .ZAT)
|
||||
let zrtTokenJWT = generateToken(accountId: try account.requireID(), expires: zrtExpiry, type: .ZRT)
|
||||
let zatSession = try Session(account: account, expires: zatExpiry, type: .ZAT)
|
||||
let zrtSession = try Session(account: account, expires: zrtExpiry, type: .ZRT)
|
||||
try await zatSession.create(on: req.db)
|
||||
try await zrtSession.create(on: req.db)
|
||||
|
||||
let zatToken = try await req.jwt.sign(zatTokenJWT)
|
||||
let zrtToken = try await req.jwt.sign(zrtTokenJWT)
|
||||
let zatToken = try zatSession.requireID()
|
||||
let zrtToken = try zrtSession.requireID()
|
||||
|
||||
let res = LoginDeviceRes(
|
||||
zatExpiryTime: Int(zatExpiry.timeIntervalSince1970) * 1000,
|
||||
@@ -119,18 +134,20 @@ struct AuthController: RouteCollection {
|
||||
@Sendable
|
||||
func zatLogin(req: Request) async throws -> LoginDeviceRes {
|
||||
let body = try req.content.decode(ZatLoginReq.self, as: .json)
|
||||
if let session = try? await req.jwt.verify(body.zat, as: SessionPayload.self) {
|
||||
guard session.type == SessionType.ZAT.rawValue && session.accountId.value == body.playerId else {
|
||||
if let session = try await Session.query(on: req.db).filter(\.$id == body.zat).first() {
|
||||
guard let accountId = Int(body.playerId), session.type == SessionType.ZAT && session.$account.id == accountId else {
|
||||
throw Abort(.badRequest, reason: "Invalid zat provided.")
|
||||
}
|
||||
try await session.delete(on: req.db)
|
||||
}
|
||||
|
||||
guard
|
||||
let accountId = Int(body.playerId),
|
||||
let account = try await Account.query(on: req.db)
|
||||
.filter(\.$id == accountId)
|
||||
.first()
|
||||
else {
|
||||
throw Abort(.badRequest, reason: "Invalid playerId")
|
||||
throw Abort(.unauthorized, reason: "Invalid playerId")
|
||||
}
|
||||
|
||||
account.lastLogin = Date.now
|
||||
@@ -138,8 +155,9 @@ struct AuthController: RouteCollection {
|
||||
|
||||
let zatExpiry = Date.now.advanced(by: 43200)
|
||||
|
||||
let session = generateToken(accountId: try account.requireID(), expires: zatExpiry, type: SessionType.ZAT)
|
||||
let zatToken = try await req.jwt.sign(session)
|
||||
let session = try Session(account: account, expires: zatExpiry, type: SessionType.ZAT)
|
||||
try await session.create(on: req.db)
|
||||
let zatToken = try session.requireID()
|
||||
return LoginDeviceRes(
|
||||
zatExpiryTime: Int(zatExpiry.timeIntervalSince1970) * 1000,
|
||||
zrtExpiryTime: nil,
|
||||
@@ -303,8 +321,3 @@ struct PushOptionResponse: Content {
|
||||
let player: String
|
||||
}
|
||||
|
||||
enum SessionType: Int {
|
||||
case ZAT = 0
|
||||
case ZRT = 1
|
||||
case VIEWER = 2
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import Vapor
|
||||
import JWT
|
||||
import Fluent
|
||||
|
||||
struct OpenApiController: RouteCollection {
|
||||
func boot(routes: any RoutesBuilder) throws {
|
||||
@@ -17,10 +17,13 @@ struct OpenApiController: RouteCollection {
|
||||
guard let zatToken = req.headers["zat"].first else {
|
||||
throw Abort(.badRequest, reason: "Missing zat header.")
|
||||
}
|
||||
let jwt = try await req.jwt.verify(zatToken, as: SessionPayload.self)
|
||||
guard jwt.accountId.value == beat.playerId else {
|
||||
|
||||
guard let session = try await Session.query(on: req.db).filter(\.$id == zatToken).first(),
|
||||
let playerId = Int(beat.playerId),
|
||||
session.$account.id == playerId else {
|
||||
throw Abort(.unauthorized, reason: "zat invalid")
|
||||
}
|
||||
|
||||
return "{}"
|
||||
}
|
||||
|
||||
@@ -29,8 +32,9 @@ struct OpenApiController: RouteCollection {
|
||||
guard let zatToken = req.headers["zat"].first else {
|
||||
throw Abort(.badRequest, reason: "Missing zat header.")
|
||||
}
|
||||
let jwt = try await req.jwt.verify(zatToken, as: SessionPayload.self)
|
||||
guard jwt.accountId.value == beat.playerId else {
|
||||
guard let session = try await Session.query(on: req.db).filter(\.$id == zatToken).first(),
|
||||
let playerId = Int(beat.playerId),
|
||||
session.$account.id == playerId else {
|
||||
throw Abort(.unauthorized, reason: "zat invalid")
|
||||
}
|
||||
return "{}"
|
||||
|
Reference in New Issue
Block a user