Skip to content

Commit 0a6af1c

Browse files
authored
feat: Added support for a "token" query parameter in diag tool. (#728)
1 parent 4626e7f commit 0a6af1c

File tree

4 files changed

+54
-29
lines changed

4 files changed

+54
-29
lines changed

.changeset/young-maps-grin.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@powersync/diagnostics-app': patch
3+
---
4+
5+
Added support for a "token" query parameter, when supplied to the root URL it will be used as the API token for the diagnostics tool instead of needing to be provided manually to the login form.

tools/diagnostics-app/src/app/page.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,33 @@
11
import React from 'react';
22
import { CircularProgress, Grid, styled } from '@mui/material';
3-
import { useNavigate } from 'react-router-dom';
3+
import { useNavigate, useSearchParams } from 'react-router-dom';
44
import { DEFAULT_ENTRY_ROUTE, LOGIN_ROUTE } from './router';
55
import { connector } from '@/library/powersync/ConnectionManager';
6+
import { getTokenEndpoint } from '@/library/powersync/TokenConnector';
7+
import { SyncClientImplementation } from '@powersync/web';
68

79
export default function EntryPage() {
810
const navigate = useNavigate();
11+
const [searchParams] = useSearchParams();
912

1013
React.useEffect(() => {
11-
if (connector.hasCredentials()) {
14+
if (searchParams.has('token')) {
15+
(async () => {
16+
const token = searchParams.get('token')!;
17+
const endpoint = getTokenEndpoint(token);
18+
if (endpoint == null) {
19+
throw new Error('endpoint is required');
20+
}
21+
22+
await connector.signIn({
23+
token,
24+
endpoint,
25+
clientImplementation: SyncClientImplementation.RUST
26+
});
27+
28+
navigate(DEFAULT_ENTRY_ROUTE);
29+
})();
30+
} else if (connector.hasCredentials()) {
1231
navigate(DEFAULT_ENTRY_ROUTE);
1332
} else {
1433
navigate(LOGIN_ROUTE);

tools/diagnostics-app/src/components/widgets/LoginDetailsWidget.tsx

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
} from '@mui/material';
1414
import { Formik, FormikErrors } from 'formik';
1515
import { SyncClientImplementation } from '@powersync/web';
16+
import { getTokenEndpoint } from '@/library/powersync/TokenConnector';
1617

1718
export type LoginDetailsFormValues = {
1819
token: string;
@@ -192,30 +193,3 @@ namespace S {
192193
margin-bottom: 20px;
193194
`;
194195
}
195-
196-
function getTokenEndpoint(token: string) {
197-
try {
198-
const [head, body, signature] = token.split('.');
199-
const payload = JSON.parse(atob(body));
200-
const aud = payload.aud as string | string[] | undefined;
201-
const audiences = Array.isArray(aud) ? aud : [aud];
202-
203-
// Prioritize public powersync URL
204-
for (let aud of audiences) {
205-
if (aud?.match(/^https?:.*.journeyapps.com/)) {
206-
return aud;
207-
}
208-
}
209-
210-
// Fallback to any URL
211-
for (let aud of audiences) {
212-
if (aud?.match(/^https?:/)) {
213-
return aud;
214-
}
215-
}
216-
217-
return null;
218-
} catch (e) {
219-
return null;
220-
}
221-
}

tools/diagnostics-app/src/library/powersync/TokenConnector.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,30 @@ function checkJWT(token: string) {
7878
throw new Error(`Token must be a JWT: Not all parts are base64 encoded`);
7979
}
8080
}
81+
82+
export function getTokenEndpoint(token: string): string | null {
83+
try {
84+
const [head, body, signature] = token.split('.');
85+
const payload = JSON.parse(atob(body));
86+
const aud = payload.aud as string | string[] | undefined;
87+
const audiences = Array.isArray(aud) ? aud : [aud];
88+
89+
// Prioritize public powersync URL
90+
for (let aud of audiences) {
91+
if (aud?.match(/^https?:.*.journeyapps.com/)) {
92+
return aud;
93+
}
94+
}
95+
96+
// Fallback to any URL
97+
for (let aud of audiences) {
98+
if (aud?.match(/^https?:/)) {
99+
return aud;
100+
}
101+
}
102+
103+
return null;
104+
} catch (e) {
105+
return null;
106+
}
107+
}

0 commit comments

Comments
 (0)