@@ -3,11 +3,12 @@ import Joi from "joi";
33import jwtLib from "jsonwebtoken" ;
44import { jwtMiddleware } from "../utils/jwt.js" ;
55import { asyncHandler } from "../utils/async.js" ;
6- import { getEntityToken , getPlayFabInventory } from "../services/playfab.service.js" ;
6+ import { getEntityToken , getPlayFabInventory , loginWithXbox } from "../services/playfab.service.js" ;
77import { getMCBalances , getMCInventory } from "../services/minecraft.service.js" ;
88import { badRequest } from "../utils/httpError.js" ;
99
1010const router = express . Router ( ) ;
11+ const PLAYFAB_TEST_TITLE_ID = "e9d1" ;
1112
1213/**
1314 * @swagger
@@ -66,6 +67,77 @@ router.post("/playfab", jwtMiddleware, asyncHandler(async (req, res) => {
6667 res . json ( { entity : entityData . Entity , items : inv . Items || [ ] } ) ;
6768} ) ) ;
6869
70+ /**
71+ * @swagger
72+ * /inventory/playfab/test:
73+ * post:
74+ * summary: Test PlayFab inventory for title id e9d1
75+ * description: >
76+ * Logs in with a PlayFab XSTS token, exchanges for an EntityToken, and returns inventory
77+ * items for the selected entity type using title id e9d1.
78+ * tags: [Inventory]
79+ * security:
80+ * - BearerAuth: []
81+ * requestBody:
82+ * required: true
83+ * content:
84+ * application/json:
85+ * schema:
86+ * type: object
87+ * required: [playfabToken]
88+ * properties:
89+ * playfabToken:
90+ * type: string
91+ * description: PlayFab XSTS token in the form XBL3.0 x={uhs};{token}
92+ * entityType:
93+ * type: string
94+ * enum: [title_player_account, master_player_account]
95+ * default: title_player_account
96+ * entityId:
97+ * type: string
98+ * description: Optional entity id override for the chosen entity type
99+ * collectionId:
100+ * type: string
101+ * default: "default"
102+ * count:
103+ * type: integer
104+ * default: 50
105+ * minimum: 1
106+ * maximum: 200
107+ * responses:
108+ * 200:
109+ * description: PlayFab inventory items for the chosen entity
110+ */
111+ router . post ( "/playfab/test" , jwtMiddleware , asyncHandler ( async ( req , res ) => {
112+ const schema = Joi . object ( {
113+ playfabToken : Joi . string ( ) . required ( ) ,
114+ entityType : Joi . string ( ) . valid ( "title_player_account" , "master_player_account" ) . default ( "title_player_account" ) ,
115+ entityId : Joi . string ( ) . optional ( ) ,
116+ collectionId : Joi . string ( ) . default ( "default" ) ,
117+ count : Joi . number ( ) . integer ( ) . min ( 1 ) . max ( 200 ) . default ( 50 )
118+ } ) ;
119+ const { value, error} = schema . validate ( req . body ) ;
120+ if ( error ) throw badRequest ( error . message ) ;
121+
122+ const loginData = await loginWithXbox ( value . playfabToken , PLAYFAB_TEST_TITLE_ID ) ;
123+ const sessionTicket = loginData . SessionTicket ;
124+ const playFabId = loginData . PlayFabId ;
125+ if ( value . entityType === "master_player_account" && ! value . entityId && ! playFabId ) {
126+ throw badRequest ( "PlayFabId is required for master_player_account" ) ;
127+ }
128+
129+ const entityOverride = value . entityId ? {
130+ Type : value . entityType , Id : value . entityId
131+ } : value . entityType === "master_player_account" ? {
132+ Type : value . entityType , Id : playFabId
133+ } : null ;
134+
135+ const entityData = await getEntityToken ( sessionTicket , entityOverride || undefined , PLAYFAB_TEST_TITLE_ID ) ;
136+ const inv = await getPlayFabInventory ( entityData . EntityToken , entityData . Entity . Id , entityData . Entity . Type , value . collectionId , value . count , PLAYFAB_TEST_TITLE_ID ) ;
137+
138+ res . json ( { entity : entityData . Entity , items : inv . Items || [ ] } ) ;
139+ } ) ) ;
140+
69141/**
70142 * @swagger
71143 * /inventory/minecraft:
0 commit comments