Skip to content

Commit 5ec01f0

Browse files
committed
Update module docs
1 parent 52d7c32 commit 5ec01f0

File tree

12 files changed

+2210
-254
lines changed

12 files changed

+2210
-254
lines changed

skip-repositories.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ export const integrationFrameworks = [
1717
{ repo: 'skip-auth0', name: 'Auth0' },
1818
{ repo: 'skip-av', name: 'AVKit' },
1919
{ repo: 'skip-bluetooth', name: 'Bluetooth' },
20-
{ repo: 'skip-kit', name: 'Camera & Media' },
20+
{ repo: 'skip-kit', name: 'App Support' },
2121
{ repo: 'skip-device', name: 'Device Hardware' },
2222
{ repo: 'skip-ffi', name: 'FFI' },
2323
{ repo: 'skip-firebase', name: 'Firebase' },
2424
{ repo: 'skip-script', name: 'JavaScriptCore' },
2525
{ repo: 'skip-keychain', name: 'Keychain' },
26+
{ repo: 'skip-livekit', name: 'WebRTC (LiveKit)' },
2627
{ repo: 'skip-marketplace', name: 'Marketplace' },
2728
{ repo: 'skip-motion', name: 'Lottie' },
2829
{ repo: 'skip-nfc', name: 'NFC' },

src/content/docs/docs/modules/skip-auth0/index.md

Lines changed: 298 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,305 @@ This framework is available at [github.com/skiptools/skip-auth0](https://github.
1010
:::
1111

1212

13-
This is a free Skip Swift/Kotlin library project containing the following modules:
13+
[Auth0](https://auth0.com) authentication for Skip apps on both iOS and Android.
1414

15-
SkipAuth0
15+
On iOS this wraps the [Auth0.swift](https://github.com/auth0/Auth0.swift) SDK (v2.18+). On Android, the Swift code is transpiled to Kotlin via Skip Lite and wraps the [Auth0.Android](https://github.com/auth0/Auth0.Android) SDK (v3.14).
16+
17+
## Setup
18+
19+
Add the dependency to your `Package.swift` file:
20+
21+
```swift
22+
let package = Package(
23+
name: "my-package",
24+
products: [
25+
.library(name: "MyProduct", targets: ["MyTarget"]),
26+
],
27+
dependencies: [
28+
.package(url: "https://source.skip.dev/skip-auth0.git", "0.0.0"..<"2.0.0"),
29+
],
30+
targets: [
31+
.target(name: "MyTarget", dependencies: [
32+
.product(name: "SkipAuth0", package: "skip-auth0")
33+
])
34+
]
35+
)
36+
```
37+
38+
### Auth0 Account Setup
39+
40+
1. Create an [Auth0](https://auth0.com) account and tenant.
41+
2. Create a **Native** application in your Auth0 dashboard.
42+
3. Note your **Domain**, **Client ID**, and configure the **Allowed Callback URLs** and **Allowed Logout URLs** for both platforms.
43+
44+
### iOS Configuration
45+
46+
Add your Auth0 domain and client ID to your `Info.plist`, and register the callback URL scheme:
47+
48+
```xml
49+
<key>CFBundleURLTypes</key>
50+
<array>
51+
<dict>
52+
<key>CFBundleURLSchemes</key>
53+
<array>
54+
<string>YOUR_BUNDLE_ID</string>
55+
</array>
56+
</dict>
57+
</array>
58+
```
59+
60+
In your Auth0 dashboard, add the callback URL: `YOUR_BUNDLE_ID://YOUR_AUTH0_DOMAIN/ios/YOUR_BUNDLE_ID/callback`
61+
62+
### Android Configuration
63+
64+
Add your Auth0 domain and scheme to your `AndroidManifest.xml` via Gradle manifest placeholders. In the test target's `Skip/skip.yml` this is configured as:
65+
66+
```yaml
67+
build:
68+
contents:
69+
- block: 'android'
70+
contents:
71+
- block: 'defaultConfig'
72+
contents:
73+
- 'manifestPlaceholders["auth0Domain"] = "YOUR_AUTH0_DOMAIN"'
74+
- 'manifestPlaceholders["auth0Scheme"] = "YOUR_SCHEME"'
75+
```
76+
77+
In your Auth0 dashboard, add the callback URL: `YOUR_SCHEME://YOUR_AUTH0_DOMAIN/android/YOUR_PACKAGE_NAME/callback`
78+
79+
See the Auth0 [Android quickstart](https://auth0.com/docs/quickstart/native/android) for details.
80+
81+
## Usage
82+
83+
### Configuration
84+
85+
Configure the SDK early in your app's lifecycle:
86+
87+
```swift
88+
import SkipAuth0
89+
90+
@main struct MyApp: App {
91+
init() {
92+
Auth0SDK.shared.configure(Auth0Config(
93+
domain: "yourapp.us.auth0.com",
94+
clientId: "your-client-id",
95+
scheme: "com.example.myapp" // Your URL scheme
96+
))
97+
}
98+
99+
var body: some Scene {
100+
WindowGroup {
101+
ContentView()
102+
}
103+
}
104+
}
105+
```
106+
107+
### Login with Universal Login (Web Auth)
108+
109+
The recommended approach is Auth0's Universal Login, which opens the system browser:
110+
111+
```swift
112+
Auth0SDK.shared.login { result in
113+
switch result {
114+
case .success(let credentials):
115+
print("Logged in!")
116+
print("Access token: \(credentials.accessToken ?? "")")
117+
print("ID token: \(credentials.idToken ?? "")")
118+
print("Refresh token: \(credentials.refreshToken ?? "")")
119+
print("Expires at: \(credentials.expiresAt?.description ?? "")")
120+
case .failure(let error):
121+
print("Login failed: \(error)")
122+
}
123+
}
124+
```
125+
126+
With custom scopes and audience:
127+
128+
```swift
129+
Auth0SDK.shared.login(
130+
scope: "openid profile email offline_access",
131+
audience: "https://api.example.com"
132+
) { result in
133+
// Handle result...
134+
}
135+
```
136+
137+
### Login with Email and Password
138+
139+
For direct login without opening a browser (requires enabling the "Password" grant type in your Auth0 application):
140+
141+
```swift
142+
Auth0SDK.shared.loginWithCredentials(
143+
email: "user@example.com",
144+
password: "securepassword"
145+
) { result in
146+
switch result {
147+
case .success(let credentials):
148+
print("Logged in with credentials")
149+
case .failure(let error):
150+
print("Login failed: \(error)")
151+
}
152+
}
153+
```
154+
155+
### Logout
156+
157+
```swift
158+
Auth0SDK.shared.logout { result in
159+
switch result {
160+
case .success:
161+
print("Logged out")
162+
case .failure(let error):
163+
print("Logout failed: \(error)")
164+
}
165+
}
166+
167+
// Federated logout (also logs out of the identity provider)
168+
Auth0SDK.shared.logout(federated: true) { result in
169+
// Handle result...
170+
}
171+
```
172+
173+
### Renewing Credentials
174+
175+
Refresh an expired access token using a refresh token:
176+
177+
```swift
178+
Auth0SDK.shared.renewCredentials(refreshToken: savedRefreshToken) { result in
179+
switch result {
180+
case .success(let newCredentials):
181+
print("Token renewed: \(newCredentials.accessToken ?? "")")
182+
case .failure(let error):
183+
print("Renewal failed: \(error)")
184+
}
185+
}
186+
```
187+
188+
### Credentials Manager
189+
190+
Check whether stored credentials are available:
191+
192+
```swift
193+
if Auth0SDK.shared.hasValidCredentials {
194+
print("User has valid stored credentials")
195+
} else {
196+
print("User needs to log in")
197+
}
198+
199+
// Clear stored credentials
200+
Auth0SDK.shared.clearCredentials()
201+
```
202+
203+
### SwiftUI Example
204+
205+
```swift
206+
import SwiftUI
207+
import SkipAuth0
208+
209+
struct LoginView: View {
210+
@State var isLoggedIn = false
211+
@State var errorMessage: String?
212+
213+
var body: some View {
214+
VStack(spacing: 16) {
215+
if isLoggedIn {
216+
Text("You are logged in!")
217+
Button("Log Out") {
218+
Auth0SDK.shared.logout { result in
219+
if case .success = result {
220+
isLoggedIn = false
221+
}
222+
}
223+
}
224+
} else {
225+
Text("Please log in")
226+
Button("Log In") {
227+
Auth0SDK.shared.login { result in
228+
switch result {
229+
case .success:
230+
isLoggedIn = true
231+
case .failure(let error):
232+
errorMessage = error.localizedDescription
233+
}
234+
}
235+
}
236+
}
237+
if let errorMessage {
238+
Text(errorMessage).foregroundStyle(.red)
239+
}
240+
}
241+
.padding()
242+
.onAppear {
243+
isLoggedIn = Auth0SDK.shared.hasValidCredentials
244+
}
245+
}
246+
}
247+
```
248+
249+
## API Reference
250+
251+
### Auth0SDK
252+
253+
The main singleton for all Auth0 operations.
254+
255+
| Method / Property | Description |
256+
|---|---|
257+
| `shared` | The singleton instance |
258+
| `configure(_:)` | Initialize with an `Auth0Config` |
259+
| `isConfigured: Bool` | Whether the SDK has been configured |
260+
| `config: Auth0Config?` | The current configuration |
261+
| `login(scope:audience:presenting:completion:)` | Start Universal Login (browser) |
262+
| `loginWithCredentials(email:password:scope:audience:completion:)` | Direct email/password login |
263+
| `logout(federated:presenting:completion:)` | Clear the session |
264+
| `renewCredentials(refreshToken:completion:)` | Refresh an access token |
265+
| `hasValidCredentials: Bool` | Whether stored credentials exist |
266+
| `clearCredentials()` | Remove stored credentials |
267+
268+
### Auth0Config
269+
270+
| Property | Description |
271+
|---|---|
272+
| `domain: String` | Auth0 tenant domain (e.g. `"yourapp.us.auth0.com"`) |
273+
| `clientId: String` | OAuth client ID from your Auth0 application |
274+
| `scheme: String` | URL scheme for callbacks (e.g. `"com.example.myapp"`) |
275+
| `logoutReturnTo: String?` | Optional custom return-to URL for logout |
276+
277+
### Auth0Credentials
278+
279+
| Property | Type | Description |
280+
|---|---|---|
281+
| `accessToken` | `String?` | OAuth2 access token |
282+
| `idToken` | `String?` | OpenID Connect ID token (JWT) |
283+
| `refreshToken` | `String?` | Refresh token for renewing credentials |
284+
| `tokenType` | `String?` | Token type (typically `"Bearer"`) |
285+
| `expiresAt` | `Date?` | When the access token expires |
286+
| `scope` | `String?` | Granted OAuth scopes |
287+
288+
### Auth0Error
289+
290+
| Case | Description |
291+
|---|---|
292+
| `.notConfigured` | `configure(_:)` has not been called |
293+
| `.missingPresenter` | A platform presenter is required |
294+
| `.webAuthFailed(String)` | The authentication flow failed |
295+
296+
## Limitations
297+
298+
:::warning
299+
The following features are **not yet available** in the Skip cross-platform wrapper:
300+
:::
301+
> - **Sign up** (user registration) — Available on iOS via the native Auth0.swift SDK. On Android, use the Auth0 Universal Login which includes sign-up, or call the Auth0 Authentication API directly via `#if SKIP` blocks.
302+
> - **Password reset** — Use the Universal Login page which includes a "Forgot Password" link, or use the native SDKs directly.
303+
> - **User profile** (`/userinfo` endpoint) — Not yet wrapped. Use the `idToken` JWT to decode user info client-side, or call the endpoint directly.
304+
> - **Token revocation** — Not yet wrapped. Use the native SDKs or call the Auth0 API directly.
305+
> - **Social / OAuth login** — Supported through Universal Login (the browser-based flow handles all identity providers configured in your Auth0 dashboard).
306+
> - **MFA (Multi-Factor Authentication)** — Handled by Universal Login when configured in your Auth0 dashboard. Programmatic MFA enrollment/verification is not wrapped.
307+
> - **Credentials persistence** — On Android, `saveCredentials` is not yet supported through the cross-platform API. Use `hasValidCredentials` and `clearCredentials` to manage stored state. On iOS, the full `CredentialsManager` is available via the native Auth0 SDK.
308+
309+
:::note
310+
On iOS, the full [Auth0.swift](https://github.com/auth0/Auth0.swift) API is available since SkipAuth0 re-exports it. Features like sign up, password reset, user profile, and token revocation work natively on iOS. The limitations above apply only to the cross-platform API surface on Android.
311+
:::
16312

17313
## Building
18314

0 commit comments

Comments
 (0)