From 7d07c6f09e2539a71f6ca1091ab1ee31f01d1bba Mon Sep 17 00:00:00 2001 From: Alex Perez Date: Mon, 31 Mar 2025 17:47:33 +0100 Subject: [PATCH] Added option to the authentication that allows you to pass an existing token to tado --- README.md | 1 + examples/auth.ts | 8 +++++++- src/base.ts | 27 +++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9de4633..c4ce15d 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ The following API calls are available /* Authentication */ /*********************/ tado.authenticate(refreshToken?, interval?); +tado.authenticateWithToken(token?, interval?); tado.setTokenCallback(cb); /*********************/ diff --git a/examples/auth.ts b/examples/auth.ts index 94ddd09..f8c1452 100644 --- a/examples/auth.ts +++ b/examples/auth.ts @@ -18,10 +18,16 @@ async function main(): Promise { ); console.log("------------------------------------------------"); } - await futureToken; + const token = await futureToken; const me = await tado.getMe(); console.log(me); + + const [_, futureToken2] = await tado.authenticateWithToken(token); + const token2 = await futureToken2; + console.log("new token: ", token2); + const me2 = await tado.getMe(); + console.log(me2); } main(); diff --git a/src/base.ts b/src/base.ts index 0b1f80c..3a1eee8 100644 --- a/src/base.ts +++ b/src/base.ts @@ -218,6 +218,33 @@ export class BaseTado { return [verify.data, token]; } + /** + * Authenticate with the Oauth server. An existing token may be supplied to bypass the device auth + * flow if it is still valid, otherwise the device flow is initiaited. + * + * @param existingToken - Attempt to use the provided token to re-authenticate + * @param timeout - Ignore the Tado provided timeout for device auth and use this value + * @returns A promise that resolves to either a `DeviceVerification` object for device auth flows + * and a promise of a token, or an undefined auth flow and a promise of a token, if the refresh token + * was supplied + */ + async authenticateWithToken( + existingToken?: Token, + timeout?: number, + ): Promise<[DeviceVerification | undefined, Promise]> { + const now = new Date(); + + if (existingToken?.expiry && existingToken.expiry > now) { + this.#token = existingToken; + try { + return [undefined, new Promise((resolve) => resolve(existingToken))]; + } catch { + // Refresh token is no good + } + } + return this.authenticate(existingToken?.refresh_token, timeout); + } + /** * Makes an API call to the provided URL with the specified method and data. *