Skip to content
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
6 changes: 6 additions & 0 deletions .changeset/dirty-jeans-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'magicbell': minor
'@magicbell/cli': minor
---

Auth tokens are now prioritized over api keys.
4 changes: 0 additions & 4 deletions packages/cli/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ export const api = createCommand('api')
.option('-f, --field <string...>', 'Add a field parameter in key=value format')
.option('-i, --include', 'Include HTTP response status line and headers in the output')
.option('-s, --silent', 'Do not print the response body')
.option(
'-t, --token <string>',
'The jwt token to use. Set a default with `magicbell config set token` or provide via the MAGICBELL_TOKEN env var',
)
.addOption(
new Option('-c, --credentials <scope>', 'Specify the authentication scope.')
.default('project')
Expand Down
14 changes: 13 additions & 1 deletion packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const program = createCommand()
.description('Work with MagicBell from the command line')
.version(pkg.version, '--version', 'Show magicbell version')
.option('-p, --profile <string>', 'Profile to use', process.env.MAGICBELL_PROFILE || 'default')
.option(
'-t, --token <string>',
'The jwt token to use. Set a default with `magicbell config set token` or via the MAGICBELL_TOKEN env var',
)
.option('-h, --host <string>', 'MagicBell API host', parseHost)
.option('--no-color', 'Color output', true)
.addOption(
Expand All @@ -33,10 +37,18 @@ program.hook('preAction', function (thisCommand) {

// check auth on authenticated routes, and redirect to login if not authenticated
program.hook('preAction', function (thisCommand, actionCommand) {
const { profile } = thisCommand.opts();
const { profile, token } = thisCommand.opts();

if (!token) {
thisCommand.setOptionValueWithSource('token', process.env.MAGICBELL_TOKEN, 'env');
}

const command = findTopCommand(actionCommand);
if (publicCommands.includes(command.name()) || actionCommand.name() === 'help') return;

// we don't need a profile or project credentials when a token is provided via arg or env
if (thisCommand.getOptionValue('token')) return;

const project = configStore.getProject(profile);

if (!project?.apiKey || (command.name() !== 'user' && !project?.apiSecret)) {
Expand Down
3 changes: 1 addition & 2 deletions packages/cli/src/lib/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ function getConfig(cmd: Command, options?: Partial<ProjectClientOptions | UserCl
const defaultOptions = {
apiKey: project?.apiKey,
apiSecret: project?.apiSecret,
// arg has highest prio, then env, then stored in config file
token: token || process.env.MAGICBELL_TOKEN || project.token,
token: token || project?.token,
userEmail: userEmail,
userExternalId: userExternalId,
host: host || project?.host,
Expand Down
6 changes: 5 additions & 1 deletion packages/magicbell/src/project-client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Client } from './client/client';
import { assertHasRequiredOptions } from './client/options';
import { ClientOptions, WithRequired } from './client/types';
import { isString } from './lib/utils';
import { Broadcasts } from './project-resources/broadcasts';
import { Imports } from './project-resources/imports';
import { Metrics } from './project-resources/metrics';
Expand All @@ -17,7 +18,10 @@ export class ProjectClient extends Client {
users = new Users(this);

constructor(options: ProjectClientOptions) {
assertHasRequiredOptions(options, ['apiKey', 'apiSecret']);
if (!('token' in options) || !isString(options.token)) {
assertHasRequiredOptions(options, ['apiKey', 'apiSecret']);
}

super(options);
}
}
6 changes: 5 additions & 1 deletion packages/magicbell/src/user-client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Client } from './client/client';
import { assertHasRequiredOptions } from './client/options';
import { ClientOptions, WithRequired } from './client/types';
import { isString } from './lib/utils';
import { createListener } from './resources/listen';
import { NotificationPreferences } from './user-resources/notification-preferences';
import { Notifications } from './user-resources/notifications';
Expand All @@ -21,7 +22,10 @@ export class UserClient extends Client {
subscriptions = new Subscriptions(this);

constructor(options: UserClientOptions) {
assertHasRequiredOptions(options, ['apiKey']);
if (!('token' in options) || !isString(options.token)) {
assertHasRequiredOptions(options, ['apiKey']);
}

if ('apiSecret' in options) {
throw new Error('The API secret should NOT be used on the user client.');
}
Expand Down