Skip to content

Commit d1f8396

Browse files
author
Amine
committed
Merge branch 'main' into expose-connection-params
# Conflicts: # tools/diagnostics-app/CHANGELOG.md # tools/diagnostics-app/package.json
2 parents c2bc2c1 + 76ea89c commit d1f8396

File tree

5 files changed

+56
-30
lines changed

5 files changed

+56
-30
lines changed

tools/diagnostics-app/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# diagnostics-app
22

3+
## 0.9.12
4+
5+
### Patch Changes
6+
7+
- 0a6af1c: 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.
8+
39
## 0.9.11
410

511
### Patch Changes

tools/diagnostics-app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@powersync/diagnostics-app",
3-
"version": "0.9.11",
3+
"version": "0.9.12",
44
"private": true,
55
"scripts": {
66
"dev": "vite",

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)