implement /infodesk endpoints
This commit is contained in:
188
Sources/stella/Controllers/InfodeskController.swift
Normal file
188
Sources/stella/Controllers/InfodeskController.swift
Normal file
@@ -0,0 +1,188 @@
|
||||
import Fluent
|
||||
import Vapor
|
||||
|
||||
struct InfodeskController: RouteCollection {
|
||||
func boot(routes: any RoutesBuilder) throws {
|
||||
let group = routes.grouped("infodesk", "v2")
|
||||
|
||||
group.get("appGroup", use: self.appGroup)
|
||||
group.get("app", use: self.app)
|
||||
}
|
||||
|
||||
@Sendable
|
||||
func appGroup(req: Request) async throws -> Response {
|
||||
var headers = HTTPHeaders()
|
||||
headers.add(name: "sig", value: "0;F8rysQxii/VL6Rca6Gnw/lq1AXA0N1RfAkKHosaiYWM=")
|
||||
return Response(status: .ok, headers: headers, body: .init(string: """
|
||||
{
|
||||
"status": 200,
|
||||
"desc": "OK",
|
||||
"content": {
|
||||
"timestamp": 1717794472083,
|
||||
"apps": [
|
||||
{
|
||||
"notices": [],
|
||||
"appId": "535877",
|
||||
"dataMap": {
|
||||
"countryCodes": "kr",
|
||||
"countryCodeList": "kr",
|
||||
"displayName": "\u{c6d4}\u{b4dc} \u{d50c}\u{b9ac}\u{d37c}",
|
||||
"forceServerSelectDeviceList": "iPad6,4 iPad7,2 iPad7,4 iPad13,6",
|
||||
"bannedCountryCodeList": "-",
|
||||
"isServiceAvailable": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"notices": [],
|
||||
"appId": "561429",
|
||||
"dataMap": {
|
||||
"countryCodes": "us",
|
||||
"countryCodeList": "ag,ai,an,ar,aw,bb,bl,bm,bo,bq,br,bs,bz,ca,cl,co,cr,cu,cw,dm,do,ec,fk,gd,gf,gp,gs,gt,gy,hn,ht,jm,kn,ky,lc,mf,mq,ms,mx,ni,pa,pe,pm,pr,py,sr,sv,sx,tc,tt,um,us,uy,vc,ve,vg,vi",
|
||||
"displayName": "World Flipper (NA)",
|
||||
"forceServerSelectDeviceList": "iPad6,4 iPad7,2 iPad7,4 iPad13,6",
|
||||
"bannedCountryCodeList": "-",
|
||||
"isServiceAvailable": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"notices": [],
|
||||
"appId": "561430",
|
||||
"dataMap": {
|
||||
"countryCodes": "de",
|
||||
"countryCodeList": "ad,ae,al,am,ao,at,ax,az,ba,be,bf,bg,bh,bi,bj,bv,bw,by,cd,cf,cg,ch,ci,cm,cv,cy,cz,de,dj,dk,dz,ee,eg,eh,er,es,et,fi,fo,fr,ga,gb,ge,gg,gh,gi,gl,gm,gn,gq,gr,gw,hr,hu,ie,il,im,iq,ir,is,it,je,jo,ke,km,kw,lb,li,lr,ls,lt,lu,lv,ly,ma,mc,md,me,mg,mk,ml,mr,mt,mu,mw,mz,na,ne,ng,nl,no,om,pl,ps,pt,qa,re,ro,rs,ru,rw,sa,sc,sd,se,sh,si,sj,sk,sl,sm,sn,so,ss,st,sy,sz,td,tf,tg,tn,tr,tz,ua,ug,uz,va,ye,yt,za,zm,zw",
|
||||
"displayName": "World Flipper (EU)",
|
||||
"forceServerSelectDeviceList": "iPad6,4 iPad7,2 iPad7,4 iPad13,6",
|
||||
"bannedCountryCodeList": "-",
|
||||
"isServiceAvailable": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"notices": [],
|
||||
"appId": "561432",
|
||||
"dataMap": {
|
||||
"countryCodes": "th",
|
||||
"countryCodeList": "af,as,au,bd,bn,bt,cc,ck,cx,fj,fm,gu,hm,id,in,io,kg,kh,ki,kz,la,lk,mh,mm,mn,mp,mv,my,nc,nf,np,nr,nu,nz,pf,pg,ph,pk,pn,pw,sb,sg,th,tj,tk,tl,tm,to,tv,vn,vu,wf,ws",
|
||||
"displayName": "World Flipper (SEA)",
|
||||
"forceServerSelectDeviceList": "iPad6,4 iPad7,2 iPad7,4 iPad13,6",
|
||||
"bannedCountryCodeList": "-",
|
||||
"isServiceAvailable": "true"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
"""))
|
||||
}
|
||||
|
||||
@Sendable
|
||||
func app(req: Request) async throws -> Response {
|
||||
var headers = HTTPHeaders()
|
||||
headers.add(name: "sig", value: "0;F8rysQxii/VL6Rca6Gnw/lq1AXA0N1RfAkKHosaiYWM=")
|
||||
return Response(status: .ok, headers: headers, body: .init(string: #"""
|
||||
{
|
||||
"status": 200,
|
||||
"desc": "OK",
|
||||
"content": {
|
||||
"supportedFeatures": [
|
||||
"urgentNotice",
|
||||
"maintenance",
|
||||
"push",
|
||||
"delivery",
|
||||
"promotion",
|
||||
"coupon",
|
||||
"notice"
|
||||
],
|
||||
"marketUrl": "market://details?id=com.kakaogames.wdfp",
|
||||
"publicKeyMap": {},
|
||||
"secondaryPwOption": null,
|
||||
"capriAppOption": {
|
||||
"ageLimit": 0,
|
||||
"lazyAgeAuth": null,
|
||||
"appType": "LEGACY_PARTNER",
|
||||
"appCategory": "Games",
|
||||
"ageAuthLevel": "NONE"
|
||||
},
|
||||
"isTubeApp": false,
|
||||
"verRecent": "0.0.81",
|
||||
"appOption": {
|
||||
"urlCommunity": "https://twitter.com/Worldflipper_kg",
|
||||
"urlOtherMenuOfficialCafe": "https://twitter.com/Worldflipper_kg",
|
||||
"urlTitleMenuContact": "oqupie",
|
||||
"cdnAddr": "http://patch.wdfp.kakaogames.com/Live/2.0.0",
|
||||
"agreementUrl": "https://web-data-game.kakaocdn.net/real/www/html/agreement/index.html?tid=13",
|
||||
"useCoupon": "true",
|
||||
"useGoogleGame": "FALSE",
|
||||
"urlPrivacyPolicy": "https://web-data-cdn.kakaogames.com/real/www/html/terms/index.html?service=S0001&type=T003",
|
||||
"urlFriendFollowServer": "https://na.wdfp.kakaogames.com",
|
||||
"useHttpHeartbeat": "true",
|
||||
"isReproduceS3UploadOpen": "false",
|
||||
"urlTermsAndConditions": "https://web-data-game.kakaocdn.net/real/www/html/terms/index.html?service=S0001&type=T001&country=us&lang=en",
|
||||
"urlHomeNews": "https://worldflipper.playkakaogames.com/news",
|
||||
"gameServerAddr": "https://na.wdfp.kakaogames.com",
|
||||
"modTime": 1617070960617,
|
||||
"urlTitleMenuNews": "https://worldflipper.playkakaogames.com/news",
|
||||
"refreshInfodeskIntervalMin": "5",
|
||||
"urlOtherMenuContact": "oqupie",
|
||||
"urlNotice": "https://worldflipper.playkakaogames.com/news",
|
||||
"urlReviewContact": "https://kakaogames.oqupie.com/portals/2060"
|
||||
},
|
||||
"notices": [],
|
||||
"traceSampleRate": 0,
|
||||
"isWhitelist": false,
|
||||
"svcStatus": "open",
|
||||
"supportedIdpCodes": [
|
||||
"facebook",
|
||||
"google",
|
||||
"siwa",
|
||||
"zd3"
|
||||
],
|
||||
"serverConnectionType": "https",
|
||||
"appVerStatus": "noNeedToUpdate",
|
||||
"publisher": {
|
||||
"privacyUrl": "https://www.kakao.com/ko/privacy",
|
||||
"privacySummaryUrl": "https://gameevent.kakao.com/supports/terms/3?tabbar=false",
|
||||
"noticeUrl2": "https://cus-zinny3.kakaogames.com/view/notice",
|
||||
"agreementUrl": "https://web-data-game.kakaocdn.net/real/www/html/agreement/index.html?tid=13",
|
||||
"servicePolicyUrl": "https://gameevent.kakao.com/terms/operation",
|
||||
"termsUrl": "https://gameevent.kakao.com/supports/terms/1",
|
||||
"kakaogameCommunityUrl": "https://playgame.kakao.com/bridge/auth/zinny",
|
||||
"termsSummaryUrl": "https://gameevent.kakao.com/supports/terms/1?tabbar=false",
|
||||
"eventWallUrl": "https://cus-zinny3.kakaogames.com/view/event",
|
||||
"noticeUrl": "https://cus-zinny3.kakaogames.com/notice",
|
||||
"customerServiceUrl": "https://cus-zinny3.kakaogames.com/support/list",
|
||||
"eventWinnerUrl": "http://event-winner.kakaogames.com/event",
|
||||
"policyVer": "1.0",
|
||||
"publisherId": "kakao",
|
||||
"modTime": 1651813742832
|
||||
},
|
||||
"sdk": {
|
||||
"heartbeatInterval": 120000,
|
||||
"PercentOfSendingAPICallLog": 0,
|
||||
"stopSendGeoDNS": "y",
|
||||
"snsShareUrl": "https://invite.kakaogame.com",
|
||||
"zrtiOSError": "{\"kakaocapri\":[500, 502, 503, -1, -7, -9]}",
|
||||
"aesEncryptKey": "djfdskj12328438djdgjcjeejhdew15",
|
||||
"aesEncryptIV": "7gnfn7f96rnanmt1s5iaa3kdruhuneu",
|
||||
"cafeLoginUrl": "https://accounts.kakao.com/weblogin/sso_login?token={tgt_token}&token_type=tgt&continue={url}",
|
||||
"zrtAOSError": "{\"kakaocapri\":[500, 502, 503, -1, -7, -9],\"google\":[8]}",
|
||||
"zrtWindowsError": "{\"kakaocapri\":[500, 502, 503, -1, -7, -9]}",
|
||||
"snsShareHostUrl": "https://invite.kakaogame.com/host/main",
|
||||
"invitationUrl": "https://webinvite.nzincorp.com",
|
||||
"csUrl": "http://customer.kakaogames.com:18080",
|
||||
"platformVersion": 3,
|
||||
"sessionTimeout": 10000,
|
||||
"registerDeviceUrl": "https://device-enrollment.kakaogames.com/main",
|
||||
"customDialogModels": [
|
||||
"SM-T976N"
|
||||
],
|
||||
"unregisterAgreementUrl": "https://web-data-cdn.kakaogames.com/real/www/html/terms/index.html?service=S0001&type=T016",
|
||||
"snsShareGuestUrl": "https://invite.kakaogame.com/guest/reward"
|
||||
},
|
||||
"deviceSecurityOption": null,
|
||||
"onlineNotifications": [],
|
||||
"timestamp": 1717794472611
|
||||
}
|
||||
}
|
||||
"""#))
|
||||
}
|
||||
}
|
@@ -1,37 +0,0 @@
|
||||
import Fluent
|
||||
import Vapor
|
||||
|
||||
struct TodoController: RouteCollection {
|
||||
func boot(routes: any RoutesBuilder) throws {
|
||||
let todos = routes.grouped("todos")
|
||||
|
||||
todos.get(use: self.index)
|
||||
todos.post(use: self.create)
|
||||
todos.group(":todoID") { todo in
|
||||
todo.delete(use: self.delete)
|
||||
}
|
||||
}
|
||||
|
||||
@Sendable
|
||||
func index(req: Request) async throws -> [TodoDTO] {
|
||||
try await Todo.query(on: req.db).all().map { $0.toDTO() }
|
||||
}
|
||||
|
||||
@Sendable
|
||||
func create(req: Request) async throws -> TodoDTO {
|
||||
let todo = try req.content.decode(TodoDTO.self).toModel()
|
||||
|
||||
try await todo.save(on: req.db)
|
||||
return todo.toDTO()
|
||||
}
|
||||
|
||||
@Sendable
|
||||
func delete(req: Request) async throws -> HTTPStatus {
|
||||
guard let todo = try await Todo.find(req.parameters.get("todoID"), on: req.db) else {
|
||||
throw Abort(.notFound)
|
||||
}
|
||||
|
||||
try await todo.delete(on: req.db)
|
||||
return .noContent
|
||||
}
|
||||
}
|
@@ -8,9 +8,11 @@ public func configure(_ app: Application) async throws {
|
||||
// uncomment to serve files from /Public folder
|
||||
// app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
|
||||
|
||||
app.databases.use(DatabaseConfigurationFactory.sqlite(.file("db.sqlite")), as: .sqlite)
|
||||
app.databases.use(DatabaseConfigurationFactory.sqlite(.file("db.sqlite")), as: .sqlite)
|
||||
|
||||
app.migrations.add(CreateTodo())
|
||||
app.http.server.configuration.hostname = "0.0.0.0"
|
||||
app.http.server.configuration.port = 8000
|
||||
|
||||
// register routes
|
||||
try routes(app)
|
||||
|
140
Sources/stella/routes/openapi.swift
Normal file
140
Sources/stella/routes/openapi.swift
Normal file
@@ -0,0 +1,140 @@
|
||||
import Vapor
|
||||
|
||||
struct OpenApi {
|
||||
func registerRoutes(_ app: Application) {
|
||||
let group = app.grouped("openapi", "service")
|
||||
|
||||
group.post("v3", "util", "country", "get") { req async -> String in
|
||||
"{\"country\": \"us\"}"
|
||||
}
|
||||
|
||||
group.post("v4", "device", "accessToken", "create") { req async -> AccessTokenResponse in
|
||||
AccessTokenResponse(accessToken: "fwPla7fQ8ty9+DZT/lD//uWZD4uD6C4lD6gGIIZTLKRTQ52/SLCRmk/370jcWGs+e+1iSoZtL7lj8ov9B0/jHmijH4nsHPQT6pchaQM1M9mtwYNQq0BWhVr9hF0jjCK/a5LIVd1kBac/Gemv29WKEDKSrUS9HxxUigoPRwtOy8m+oDj9FmDJZ+rzqWCc0QjES4Ky0fTpXZ7ESoguDzNmRtW3FYr+OFexw8wBPlwiC4w=", expiryTime: Int(Date.init(timeIntervalSinceNow: .init(0)).timeIntervalSince1970))
|
||||
}
|
||||
|
||||
group.post("v3", "agreement", "getForLogin") { req async throws -> String in
|
||||
let body = try req.content.decode(LoginAgreementRequest.self, as: .json)
|
||||
|
||||
return #"""
|
||||
{
|
||||
"adAgreementStatus": "n",
|
||||
"agreement": {
|
||||
"E001": "n",
|
||||
"E002": "n",
|
||||
"E006": "n",
|
||||
"N002": "n",
|
||||
"N003": "n",
|
||||
"timestamp": "\#(Int(Date().timeIntervalSince1970) * 1000)"
|
||||
},
|
||||
"agreementPopup": "n",
|
||||
"appId": "\#(body.appId)",
|
||||
"appName": "World Flipper (NA)",
|
||||
"context": "login",
|
||||
"country": "\#(body.country)",
|
||||
"firstAgreement": "n",
|
||||
"idpCode": "\#(body.idpCode)",
|
||||
"idpId": "6076008646",
|
||||
"informationSecurityCountry": "kr",
|
||||
"kakaoSyncAgreementGetSet": "n",
|
||||
"kakaoSyncStatus": "off",
|
||||
"kakaogameSdkVer": "3.0",
|
||||
"lang": "\#(body.lang)",
|
||||
"partnerId": 825,
|
||||
"partnerName": "주식회사 카카오게임즈",
|
||||
"plusFriendStatusInfo": null,
|
||||
"policyApplyTime": 1630854000000
|
||||
}
|
||||
"""#
|
||||
}
|
||||
|
||||
group.post("v4", "auth", "loginDevice") { req async throws -> Response in
|
||||
let body = try req.content.decode(LoginDeviceRequest.self, as: .json)
|
||||
dump(body)
|
||||
if let rawAccountId = req.headers["playerId"].first {
|
||||
|
||||
}
|
||||
return Response(status: .notImplemented)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AccessTokenResponse: Content {
|
||||
let accessToken: String
|
||||
let expiryTime: Int
|
||||
}
|
||||
|
||||
struct LoginAgreementRequest: Content {
|
||||
let deviceId: String
|
||||
let os: String
|
||||
let country: String
|
||||
let lang: String
|
||||
let appId: String
|
||||
let idpCode: String
|
||||
let serialNo: String
|
||||
let idpId: String
|
||||
}
|
||||
|
||||
struct LoginDeviceRequest: Content {
|
||||
let lang: String
|
||||
let clientTime: Int
|
||||
let deviceId: String
|
||||
let serialNo: String
|
||||
let country: String
|
||||
let whiteKey: String
|
||||
let market: String
|
||||
let appSecret: String
|
||||
let deviceAppKey: String
|
||||
let sdkVer: String
|
||||
let appVer: String
|
||||
let os: String
|
||||
let loginType: String
|
||||
let accessToken: String
|
||||
let resume: Bool
|
||||
let osVer: String
|
||||
let appId: String
|
||||
let deviceModel: String
|
||||
let network: String
|
||||
let isIosAppOnMac: Bool
|
||||
let adid: String
|
||||
let timezoneOffset: Int
|
||||
let fields: [String]
|
||||
let telecom: String
|
||||
}
|
||||
|
||||
struct LoginDeviceResponse: Content {
|
||||
let zatExpiryTime: Int
|
||||
let zrtExpiryTime: Int
|
||||
let firstLogin: Bool
|
||||
let externalToken: String
|
||||
let zat: String
|
||||
let zrt: String
|
||||
let player: Player
|
||||
}
|
||||
|
||||
struct Player: Content {
|
||||
let idpId: String
|
||||
let appId: String
|
||||
let lang: String
|
||||
let playerId: String
|
||||
let agreement: AgreementResponse
|
||||
let pushOption: PushOptionResponse
|
||||
let lastLoginTime: Int
|
||||
let regTime: Int
|
||||
let idpAlias: String
|
||||
let firstLoginTime: Int
|
||||
let status: String
|
||||
}
|
||||
|
||||
struct AgreementResponse: Content {
|
||||
let E001: String
|
||||
let E002: String
|
||||
let E006: String
|
||||
let N002: String
|
||||
let N003: String
|
||||
let timestamp: String
|
||||
}
|
||||
|
||||
struct PushOptionResponse: Content {
|
||||
let night: String
|
||||
let player: String
|
||||
}
|
@@ -2,7 +2,7 @@ import Fluent
|
||||
import Vapor
|
||||
|
||||
func routes(_ app: Application) throws {
|
||||
app.get { req async in
|
||||
app.get { req async in
|
||||
"It works!"
|
||||
}
|
||||
|
||||
@@ -10,5 +10,10 @@ app.get { req async in
|
||||
"Hello, world!"
|
||||
}
|
||||
|
||||
try app.register(collection: TodoController())
|
||||
let openApi = OpenApi()
|
||||
openApi.registerRoutes(app)
|
||||
|
||||
try app.register(collection: InfodeskController())
|
||||
|
||||
print(app.routes.all)
|
||||
}
|
Reference in New Issue
Block a user