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
3 changes: 3 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
APPLE_KEY_ID=""
APPLE_PRIVATE_KEY=""
APPLE_DEVELOPER_ID=""
16 changes: 0 additions & 16 deletions .github/workflows/deploy-worker.yaml

This file was deleted.

19 changes: 19 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: pull-request

on:
pull_request:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: npm
- run: npm ci
- run: npm run generate-types
- run: npm test
31 changes: 31 additions & 0 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: push

on:
push:
branches:
- main

permissions:
contents: write
pull-requests: write

jobs:
release-please:
runs-on: ubuntu-latest
outputs:
release_created: ${{ steps.release.outputs.release_created }}
steps:
- uses: googleapis/release-please-action@v4
id: release
with:
release-type: node

deploy:
runs-on: ubuntu-latest
needs: release-please
if: ${{ needs.release-please.outputs.release_created }}
steps:
- uses: actions/checkout@v4
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ dist

.dev.vars
.wrangler/
worker-configuration.d.ts

# secrets

Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# checkd

[![deploy](https://github.com/willswire/checkd/actions/workflows/deploy-worker.yaml/badge.svg?event=release)](https://github.com/willswire/checkd/actions/workflows/deploy-worker.yaml)
[![push](https://github.com/willswire/checkd/actions/workflows/push.yml/badge.svg)](https://github.com/willswire/checkd/actions/workflows/push.yml)

checkd is a Cloudflare Workers-based server implementation for [Apple's DeviceCheck framework](https://developer.apple.com/documentation/devicecheck), enabling easy validation of requests made by valid Apple devices. This project provides both the core service worker (`checkd`) and example projects (`checkr` iOS app and worker) to demonstrate how to use checkd in an end-to-end workflow.

Expand Down Expand Up @@ -36,7 +36,7 @@ The `checkd` service worker provides the functionality to validate whether an Ap
### Key Files

- **`src/index.ts`**: The main worker file where the functionality resides.
- **`wrangler.toml`**: Configuration file for deploying the worker with Cloudflare Wrangler.
- **`wrangler.jsonc`**: Configuration file for deploying the worker with Cloudflare Wrangler.
- **`tsconfig.json`**: TypeScript configuration file.
- **Environment Variables**: These include `APPLE_KEY_ID`, `APPLE_PRIVATE_KEY`, `APPLE_DEVELOPER_ID`.

Expand Down Expand Up @@ -65,8 +65,8 @@ The `checkr` iOS App demonstrates client-side implementation:

### Key Files in Examples

- **Worker**: The main implementation file `src/index.ts` and configuration files (`wrangler.toml`, `tsconfig.json`).
- **iOS App**: `ContentView.swift` managing the UI flow, and `SessionHandler.swift` handling the DeviceCheck logic.
- **Worker**: The main implementation file `src/index.ts` and configuration files (`wrangler.jsonc`, `tsconfig.json`).
- **iOS App**: `app.swift` containing the UI (`ContentView`) and DeviceCheck logic (`SessionHandler`).

## Setup and Installation

Expand Down Expand Up @@ -104,7 +104,7 @@ cd checkd/examples/app/checkr

### Set Environment Variables

Define the required environment variables (APPLE_KEY_ID, APPLE_PRIVATE_KEY, APPLE_DEVELOPER_ID) in the `wrangler.toml` file or via the Cloudflare Dashboard.
Define the required environment variables (APPLE_KEY_ID, APPLE_PRIVATE_KEY, APPLE_DEVELOPER_ID) in the `wrangler.jsonc` file or via the Cloudflare Dashboard.

### Deploy the Cloudflare Worker

Expand Down
28 changes: 21 additions & 7 deletions examples/app/checkr/app.swift
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
import SwiftUI
import DeviceCheck

var isDevelopment: Bool {
#if targetEnvironment(simulator)
return true
#else
guard let receiptURL = Bundle.main.appStoreReceiptURL else { return false }
return receiptURL.lastPathComponent == "sandboxReceipt"
#endif
}

class SessionHandler {
var session: URLSession

init() async {
let sessionConfiguration = URLSessionConfiguration.default

let device = DCDevice.current
if device.isSupported {
print("Device supports DeviceCheck")
if let data = try? await device.generateToken() {
print("Device token: \(data.base64EncodedString())")
do {
let data = try await device.generateToken()
let tokenString = data.base64EncodedString()
sessionConfiguration.httpAdditionalHeaders = [
"X-Apple-Device-Token": tokenString,
"X-Apple-Device-Development": "true"
"X-Apple-Device-Development": String(isDevelopment)
]
} catch DCError.featureUnsupported {
print("DeviceCheck feature unsupported on this device")
} catch {
print("Failed to generate device token: \(error.localizedDescription)")
}
} else {
print("Device does not support DeviceCheck")
}

self.session = URLSession(configuration: sessionConfiguration)
}
}
Expand Down Expand Up @@ -81,6 +93,8 @@ struct ContentView: View {
}

func fetch() async {
didFail = false
errorDescription = nil
do {
if let url = URL(string: endpointURL) {
let sessionHandler = await SessionHandler()
Expand Down
Loading