| 1 | import * as web from '@solid-native/web'; |
| 2 | import * as linking from '@solid-native/linking'; |
| 3 | |
| 4 | await web.open('https://github.com/owner/repo'); |
| 5 | await linking.open('mailto:hello@example.com'); |
| 6 | |
| 7 | const off = linking.onOpen(({ url }) => { |
| 8 | // Pass through your router's configured prefixes and route validation. |
| 9 | router.openLink(url); |
| 10 | }); |
web.open uses Safari View Controller / Android Custom Tabs. Its promise acknowledges
presentation, not page load or dismissal. linking.open hands an absolute URL to
its external OS handler and rejects if it cannot open. These are not embedded
WebViews; a future WebView component belongs in @solid-native/web, not another
auth-specific browser package.
linking.onOpen allows one app-root consumer, cleaned up with its Solid owner or
the returned off. Cold and live links enter an ordered native inbox before JS
delivery. Identical URLs remain distinct. Unsubscribing leaves undelivered entries
in the inbox. Delivery acknowledges a synchronous listener invocation, not the
completion of asynchronous navigation. Listener exceptions are reported and do
not block subsequent entries. The inbox is process-local, not a persistent queue;
an abrupt process/runtime failure between delivery and acknowledgement is not an
exactly-once guarantee.
| 1 | const { verifier, challenge } = await web.createPkce(); |
| 2 | // A separate random verifier is also suitable as opaque OAuth state. |
| 3 | const state = (await web.createPkce()).verifier; |
| 4 | const redirectUrl = 'solid-native://oauth/callback'; |
| 5 | const query = Object.entries({ |
| 6 | client_id: publicClientId, |
| 7 | response_type: 'code', |
| 8 | redirect_uri: redirectUrl, |
| 9 | state, |
| 10 | code_challenge: challenge, |
| 11 | code_challenge_method: 'S256', |
| 12 | }) |
| 13 | .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) |
| 14 | .join('&'); |
| 15 | |
| 16 | const result = await web.authenticate({ |
| 17 | url: `https://your-identity-provider.example/authorize?${query}`, |
| 18 | redirectUrl, |
| 19 | state, |
| 20 | }); |
| 21 | if (result) { |
| 22 | // Exchange result.code with verifier using the provider's documented flow. |
| 23 | // Never embed a confidential OAuth client secret in the application. |
| 24 | } |
createPkce uses native cryptographic randomness and SHA-256 (RFC 7636 S256).
authenticate uses ASWebAuthenticationSession / Custom Tabs, requires an HTTPS
authorization URL and a registered custom-scheme callback, and permits one active
web presentation. It checks scheme, host, port, encoded path, exactly one matching
state, and exactly one nonempty code or OAuth error. User cancellation returns
null; malformed callbacks, state mismatch, OAuth errors, and presentation failures
reject. It does not add parameters, exchange tokens, manage refresh, persist a
session, or verify an ID token. Use fresh state and PKCE for every attempt. Do not
log callback URLs or authorization codes. HTTPS app/universal-link callbacks,
implicit-token flows, ephemeral-session controls, and process-death continuation
are not supported by this initial API.
The repository's sample host already compiles/registers all modules. It uses
solid-native://app/... for navigation and reserves solid-native://oauth/callback
for auth. Replace these with app-specific schemes in production.
Android requires androidx.browser:browser, the JSI adapter/module registration,
and both activities declared in android/app/src/main/AndroidManifest.xml:
SolidWebAuthActivity is not exported and must not be noHistory. It stays
beneath the browser to receive callbacks and recognize Back cancellation.SolidWebRedirectActivity has only the dedicated OAuth intent filter.
It forwards to the existing auth activity; late callbacks are discarded, never
sent to normal linking.MainActivity captures navigation URLs in onCreate and onNewIntent; ordinary
route filters must not overlap auth callbacks.iOS requires the package sources, CFBundleURLTypes, and forwarding application
(or scene, for a scene-based host) URL/user-activity callbacks to SolidLinking.
Reserve OAuth endpoints from this forwarding, including after an auth session
ends. ASWebAuthenticationSession owns its callback. HTTPS incoming app links also
require your signed associated-domain entitlements and server association files;
this repository does not claim a domain or configure those files for you.