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

feat: more automated oauth #52

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
24 changes: 19 additions & 5 deletions companion/HELP.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,26 @@

### Setup

Go to [here](https://developer.spotify.com/dashboard/applications) and create an application.
Copy the Client ID and Client Secret and add them to the config boxes.
Set https://spotauth.github.io/ as your Redirect URL both in the Config and on the spotify application you created.
When you save the modules config a URL will be placed on in the auth URL config box, make sure to refresh to load it, go to this URL and then copy the Approval Code into the config.
This time when you save the config an Access Token and Refresh Token will be wrote to the config.
1. Go to [here](https://developer.spotify.com/dashboard/applications) and create an application.
2. Copy the Client ID and Client Secret and add them to the config boxes. Set the application to use the Redirect URL shown.
3. Save the module config
4. Reopen the module config, copy the 'Auth URL' and open it in your browser
5. Follow through the process
6. Once you are greeted with a page reporting 'Success', you can close the tab, and the module status will now be green.

If the module status changes due to it being unable to authenticate, navigate to the 'Auth URL' again, and repeat the remaining steps of the process.

Now go assign the "Write the ID of the current Active Device to config" button, start playing music on the device you wish to control and then press the button you just assigned.
The module is now fully configured and should work without issue.

If you have an issues with the module please open an issue on the module's GitHub repo or message Peter Stather on the official Slack.

## Old Method

In previous versions, the process was a bit more manual, involving changing the Redirect URL. This still works but is no longer necessary.

1. Set https://spotauth.github.io/ as your Redirect URL both in the Config and on the spotify application you created.
2. Save the config
3. Reopen the module config, copy the 'Auth URL' and open it in your browser
4. Follow through the process
5. Copy the code provided into the 'Approval Code' field (This is hidden behind the 'Show secrets' toggle)
31 changes: 21 additions & 10 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,36 +37,47 @@ export function GetConfigFields(): SomeCompanionConfigField[] {
id: 'redirectUri',
width: 12,
label: 'Redirect URL',
default: 'https://bitfocus.github.io/companion-oauth/callback',
},
{
type: 'textinput',
id: 'code',
id: 'authURL',
width: 12,
label: 'Approval Code',
label: 'Auth URL',
},
{
type: 'textinput',
id: 'accessToken',
id: 'deviceId',
width: 12,
label: 'Access Token',
label: 'Device ID',
},
{
type: 'checkbox',
id: 'managed_secrets',
width: 12,
label: 'Show secrets',
default: false,
},
{
type: 'textinput',
id: 'refreshToken',
id: 'code',
width: 12,
label: 'Refresh Token',
label: 'Approval Code',
isVisible: (options) => !!options.managed_secrets,
},
{
type: 'textinput',
id: 'deviceId',
id: 'accessToken',
width: 12,
label: 'Device ID',
label: 'Access Token',
isVisible: (options) => !!options.managed_secrets,
},
{
type: 'textinput',
id: 'authURL',
id: 'refreshToken',
width: 12,
label: 'Auth URL',
label: 'Refresh Token',
isVisible: (options) => !!options.managed_secrets,
},
]
}
62 changes: 61 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/// <reference types="spotify-api" />

import {
CompanionHTTPRequest,
CompanionHTTPResponse,
CompanionVariableDefinition,
InstanceBase,
InstanceStatus,
Expand Down Expand Up @@ -176,7 +178,7 @@ class SpotifyInstance extends InstanceBase<DeviceConfig> implements SpotifyInsta
this.config.clientId,
this.config.redirectUri,
AUTH_SCOPES,
''
this.id
).toString()
this.saveConfig(this.config)
}
Expand Down Expand Up @@ -228,6 +230,64 @@ class SpotifyInstance extends InstanceBase<DeviceConfig> implements SpotifyInsta
getConfigFields(): SomeCompanionConfigField[] {
return GetConfigFields()
}

async handleHttpRequest(request: CompanionHTTPRequest): Promise<CompanionHTTPResponse> {
if (request.path === '/oauth/callback') {
const authCode = request.query['code']
if (!authCode) {
return {
status: 400,
body: 'Missing auth code!',
}
}

if (!this.config.clientId || !this.config.clientSecret || !this.config.redirectUri) {
return {
status: 400,
body: 'Missing required config fields!',
}
}

try {
const data = await authorizationCodeGrant(
this.config.clientId,
this.config.clientSecret,
this.config.redirectUri,
authCode
)
if (data.body?.access_token) {
this.config.accessToken = data.body.access_token
} else {
delete this.config.accessToken
}
if (data.body?.refresh_token) {
this.config.refreshToken = data.body.refresh_token
} else {
delete this.config.refreshToken
}
this.saveConfig(this.config)

this.applyConfigValues()
} catch (err: any) {
this.log('debug', `Failed to get access token: ${err?.message ?? err?.toString()}`)
return {
status: 500,
body: `Failed to authenticate\n${err?.message ?? err?.toString()}`,
}
}
// TODO

return {
status: 200,
body: 'Success!\nYou can close this tab',
}
}

return {
status: 404,
}
}

private initActions() {
const executeActionWrapper = (fcn: DoAction) => {
// Verify the api client is configured
Expand Down