···22NODE_ENV="development" # Options: 'development', 'production'
33PORT="8080" # The port your server will listen on
44HOST="localhost" # Hostname for the server
55-PUBLIC_URL="https://localhost:8080"
55+PUBLIC_URL=""
6677# CORS Settings
88CORS_ORIGIN="http://localhost:*" # Allowed CORS origin, adjust as necessary
···1212COMMON_RATE_LIMIT_MAX_REQUESTS="20" # Max number of requests per window per IP
13131414# Secrets
1515-# openssl rand -base64 33
1616-COOKIE_SECRET=""
1717-# openssl ecparam -name prime256v1 -genkey | openssl pkcs8 -topk8 -nocrypt | openssl base64 -A
1818-PRIVATE_KEY_ES256_B64=""
1515+# Must this in production. May be generated with `openssl rand -base64 33`
1616+# COOKIE_SECRET=""
+8-20
src/auth/client.ts
···55import { SessionStore, StateStore } from './storage'
6677export const createClient = async (db: Database) => {
88- const url = env.PUBLIC_URL
99- const privateKeyPKCS8 = Buffer.from(env.PRIVATE_KEY_ES256_B64, 'base64').toString()
1010- const privateKey = await JoseKey.fromImportable(privateKeyPKCS8, 'key1')
88+ const publicUrl = env.PUBLIC_URL
99+ const url = publicUrl || `http://127.0.0.1:${env.PORT}`
1110 return new NodeOAuthClient({
1212- // This object will be used to build the payload of the /client-metadata.json
1313- // endpoint metadata, exposing the client metadata to the OAuth server.
1411 clientMetadata: {
1515- // Must be a URL that will be exposing this metadata
1616- client_id: `${url}/client-metadata.json`,
1212+ client_name: 'AT Protocol Express App',
1313+ client_id: publicUrl
1414+ ? `${url}/client-metadata.json`
1515+ : `http://localhost?redirect_uri=${encodeURIComponent(`${url}/oauth/callback`)}`,
1716 client_uri: url,
1818- client_name: 'ATProto Express App',
1919- jwks_uri: `${url}/jwks.json`,
2017 logo_uri: `${url}/logo.png`,
2118 tos_uri: `${url}/tos`,
2219 policy_uri: `${url}/policy`,
2320 redirect_uris: [`${url}/oauth/callback`],
2424- token_endpoint_auth_signing_alg: 'ES256',
2525- scope: 'profile email offline_access',
2121+ scope: 'profile offline_access',
2622 grant_types: ['authorization_code', 'refresh_token'],
2723 response_types: ['code'],
2824 application_type: 'web',
2929- token_endpoint_auth_method: 'private_key_jwt',
2525+ token_endpoint_auth_method: 'none',
3026 dpop_bound_access_tokens: true,
3127 },
3232-3333- // Used to authenticate the client to the token endpoint. Will be used to
3434- // build the jwks object to be exposed on the "jwks_uri" endpoint.
3535- keyset: [privateKey],
3636-3737- // Interface to store authorization state data (during authorization flows)
3828 stateStore: new StateStore(db),
3939-4040- // Interface to store authenticated session data
4129 sessionStore: new SessionStore(db),
4230 })
4331}
···11-import type { Database } from '#/db/index'
11+import type { Database } from '#/db'
22import { Firehose } from '#/firehose/firehose'
3344export class Ingester {
-2
src/pages/login.ts
···11-import { AtUri } from '@atproto/syntax'
22-import type { Post } from '#/db/schema'
31import { html } from '../view'
42import { shell } from './shell'
53