Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: bump core SDK version #581

Merged
merged 1 commit into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/calm-worms-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@smartthings/plugin-cli-edge": patch
"@smartthings/cli-lib": patch
"@smartthings/cli-testlib": patch
"@smartthings/cli": patch
---

bump core SDK version
28 changes: 14 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
"@oclif/plugin-not-found": "^2.3.1",
"@oclif/plugin-plugins": "^2.1.0",
"@smartthings/cli-lib": "^2.2.3",
"@smartthings/core-sdk": "^8.1.1",
"@smartthings/core-sdk": "^8.1.2",
"@smartthings/plugin-cli-edge": "^3.3.2",
"inquirer": "^8.2.4",
"js-yaml": "^4.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/edge/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"@log4js-node/log4js-api": "^1.0.2",
"@oclif/core": "^1.16.3",
"@smartthings/cli-lib": "^2.2.3",
"@smartthings/core-sdk": "^8.1.1",
"@smartthings/core-sdk": "^8.1.2",
"axios": "^0.27.2",
"inquirer": "^8.2.4",
"js-yaml": "^4.1.0",
Expand Down
7 changes: 4 additions & 3 deletions packages/edge/src/lib/live-logging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,20 +217,21 @@ export class LiveLogClient {
}

private async request(url: string, method: Method = 'GET'): Promise<AxiosResponse> {
const config = await this.config.authenticator.authenticate({
const authHeaders = await this.config.authenticator.authenticate()
const config = {
url: url,
method: method,
httpsAgent: new https.Agent({ rejectUnauthorized: false }),
timeout: this.config.timeout,
// eslint-disable-next-line @typescript-eslint/naming-convention
headers: { 'User-Agent': this.config.userAgent },
headers: { 'User-Agent': this.config.userAgent, ...authHeaders },
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
// throw ETIMEDOUT error instead of generic ECONNABORTED on request timeouts
clarifyTimeoutError: true,
},
})
}

let response
try {
Expand Down
2 changes: 1 addition & 1 deletion packages/lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"dependencies": {
"@log4js-node/log4js-api": "^1.0.2",
"@oclif/core": "^1.16.3",
"@smartthings/core-sdk": "^8.1.1",
"@smartthings/core-sdk": "^8.1.2",
"@types/eventsource": "^1.1.9",
"axios": "^0.27.2",
"chalk": "^4.1.2",
Expand Down
36 changes: 6 additions & 30 deletions packages/lib/src/__tests__/login-authenticator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,31 +429,12 @@ describe('LoginAuthenticator', () => {
})

describe('authenticate', () => {
it('calls generic authenticate', async () => {
readFileMock.mockReturnValueOnce(Buffer.from(JSON.stringify(credentialsFileData)))

const genericSpy = jest.spyOn(LoginAuthenticator.prototype, 'authenticateGeneric')

const loginAuthenticator = setupAuthenticator()
const requestConfig = {}

const response = await loginAuthenticator.authenticate(requestConfig)

expect(response.headers?.Authorization).toEqual('Bearer access token')
expect(genericSpy).toBeCalledTimes(1)
})
})

describe('authenticateGeneric', () => {
it('refreshes token when necessary', async () => {
readFileMock.mockReturnValueOnce(Buffer.from(JSON.stringify(refreshableCredentialsFileData)))

const loginAuthenticator = setupAuthenticator()
const requestConfig = {}

const response = await loginAuthenticator.authenticate(requestConfig)

expect(response.headers?.Authorization).toEqual('Bearer access token')
expect(await loginAuthenticator.authenticate()).toStrictEqual({ Authorization: 'Bearer access token' })

expect(postMock).toHaveBeenCalledTimes(1)
const postData = postMock.mock.calls[0][1]
Expand All @@ -472,9 +453,8 @@ describe('LoginAuthenticator', () => {
it('includes User-Agent on refresh', async () => {
readFileMock.mockReturnValueOnce(Buffer.from(JSON.stringify(refreshableCredentialsFileData)))
const loginAuthenticator = setupAuthenticator()
const requestConfig = {}

await loginAuthenticator.authenticate(requestConfig)
await loginAuthenticator.authenticate()

expect(postMock).toHaveBeenCalledTimes(1)
expect(postMock).toHaveBeenCalledWith(
Expand All @@ -493,13 +473,11 @@ describe('LoginAuthenticator', () => {
postMock.mockResolvedValueOnce(tokenResponse)

const loginAuthenticator = setupAuthenticator()
const requestConfig = {}

const promise = loginAuthenticator.authenticate(requestConfig)
const promise = loginAuthenticator.authenticate()
await imitateBrowser()
const response = await promise

expect(response.headers?.Authorization).toEqual('Bearer access token')
expect(await promise).toStrictEqual({ Authorization: 'Bearer access token' })

expect(postMock).toHaveBeenCalledTimes(2)
const postData = postMock.mock.calls[0][1]
Expand Down Expand Up @@ -529,13 +507,11 @@ describe('LoginAuthenticator', () => {

it('logs in not logged in', async () => {
const loginAuthenticator = setupAuthenticator()
const requestConfig = {}

const promise = loginAuthenticator.authenticate(requestConfig)
const promise = loginAuthenticator.authenticate()
await imitateBrowser()
const response = await promise

expect(response.headers?.Authorization).toEqual('Bearer access token')
expect(await promise).toStrictEqual({ Authorization: 'Bearer access token' })

expect(getPortMock).toHaveBeenCalledTimes(1)
expect(getPortMock).toHaveBeenCalledWith({ port: [61973, 61974, 61975] })
Expand Down
18 changes: 3 additions & 15 deletions packages/lib/src/login-authenticator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import getPort from 'get-port'
import open from 'open'
import path from 'path'
import qs from 'qs'
import { SmartThingsURLProvider, defaultSmartThingsURLProvider, Authenticator } from '@smartthings/core-sdk'
import { SmartThingsURLProvider, defaultSmartThingsURLProvider, Authenticator, HttpClientHeaders } from '@smartthings/core-sdk'
import log4js from '@log4js-node/log4js-api'
import { CliUx } from '@oclif/core'

Expand Down Expand Up @@ -279,19 +279,7 @@ export class LoginAuthenticator implements Authenticator {
})
}

async authenticate(requestConfig: AxiosRequestConfig): Promise<AxiosRequestConfig> {
const token = await this.authenticateGeneric()

return {
...requestConfig,
headers: {
...requestConfig.headers,
Authorization: `Bearer ${token}`,
},
}
}

async authenticateGeneric(): Promise<string> {
async authenticate(): Promise<HttpClientHeaders> {
this.logger.debug('authentication - enter')
// refresh if we have less than an hour left on the auth token
if (this.authenticationInfo && this.authenticationInfo.expires.getTime() < Date.now() + 60 * 60 * 1000) {
Expand All @@ -304,7 +292,7 @@ export class LoginAuthenticator implements Authenticator {
}

if (this.authenticationInfo) {
return this.authenticationInfo.accessToken
return { Authorization: `Bearer ${this.authenticationInfo.accessToken}` }
}

throw new Error('unable to obtain user credentials')
Expand Down
6 changes: 3 additions & 3 deletions packages/lib/src/sse-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ export abstract class SseCommand<T extends typeof SseCommand.flags> extends APIC
const headers: HttpClientHeaders = { 'User-Agent': this.userAgent }

// assume auth is taken care of if passing an initDict
if (!sourceInitDict && this.authenticator.authenticateGeneric) {
const token = await this.authenticator.authenticateGeneric()
sourceInitDict = { headers: { ...headers, 'Authorization': `Bearer ${token}` } }
if (!sourceInitDict) {
const authHeaders = await this.authenticator.authenticate()
sourceInitDict = { headers: { ...headers, ...authHeaders } }
} else {
sourceInitDict = { ...sourceInitDict, headers: { ...headers, ...sourceInitDict?.headers } }
}
Expand Down
2 changes: 1 addition & 1 deletion packages/testlib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
},
"dependencies": {
"@smartthings/cli-lib": "^2.2.3",
"@smartthings/core-sdk": "^8.1.1"
"@smartthings/core-sdk": "^8.1.2"
},
"devDependencies": {
"@types/jest": "^28.1.5",
Expand Down
2 changes: 1 addition & 1 deletion packages/testlib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jest.spyOn(APICommand.prototype, 'client', 'get').mockReturnValue(new MockSmartT
* Perform minimal stubbing required to get CLI commands running under jest
*/
jest.spyOn(LoginAuthenticator.prototype, 'login').mockImplementation(() => Promise.resolve())
jest.spyOn(LoginAuthenticator.prototype, 'authenticate').mockImplementation((requestConfig) => Promise.resolve(requestConfig));
jest.spyOn(LoginAuthenticator.prototype, 'authenticate').mockImplementation(() => Promise.resolve({}));
(global as { _credentialsFile?: string })._credentialsFile = 'credentials.json'

/**
Expand Down