@oxyhq/core 1.11.16 → 1.11.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -322,6 +322,11 @@ function OxyServicesAuthMixin(Base) {
322
322
  }
323
323
  /**
324
324
  * Get access token by session ID
325
+ *
326
+ * SECURITY: this endpoint requires the caller to already hold a
327
+ * bearer token whose user owns the referenced session (C1 hardening
328
+ * in the API). For the device-flow / QR sign-in case where the
329
+ * client has no bearer token yet, use `claimSessionByToken` instead.
325
330
  */
326
331
  async getTokenBySession(sessionId) {
327
332
  try {
@@ -333,6 +338,40 @@ function OxyServicesAuthMixin(Base) {
333
338
  throw this.handleError(error);
334
339
  }
335
340
  }
341
+ /**
342
+ * Exchange a device-flow sessionToken for the first access token.
343
+ *
344
+ * The originating client holds a 128-bit `sessionToken` that nobody
345
+ * else has seen — it was generated client-side, sent once on
346
+ * `POST /auth/session/create`, and is never echoed back. After
347
+ * another authenticated device approves the session via
348
+ * `POST /auth/session/authorize/{sessionToken}` (bearer-authed) and
349
+ * the auth socket / poll loop notifies this client, the client
350
+ * exchanges its `sessionToken` here for the first access token,
351
+ * refresh token, sessionId, and the authorized user.
352
+ *
353
+ * This call requires no Authorization header — the high-entropy
354
+ * `sessionToken` IS the credential (RFC 8628 §3.4). The exchange is
355
+ * single-use; replay attempts are rejected with 401.
356
+ *
357
+ * @param sessionToken - The same sessionToken the SDK passed to
358
+ * `POST /auth/session/create` at the start of the flow.
359
+ * @param options.deviceFingerprint - Optional fingerprint of the
360
+ * originating client device.
361
+ */
362
+ async claimSessionByToken(sessionToken, options = {}) {
363
+ try {
364
+ const res = await this.makeRequest('POST', '/auth/session/claim', {
365
+ sessionToken,
366
+ ...(options.deviceFingerprint ? { deviceFingerprint: options.deviceFingerprint } : {}),
367
+ }, { cache: false, retry: false });
368
+ this.setTokens(res.accessToken, res.refreshToken);
369
+ return res;
370
+ }
371
+ catch (error) {
372
+ throw this.handleError(error);
373
+ }
374
+ }
336
375
  /**
337
376
  * Get sessions by session ID
338
377
  */