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