Skip to main content

Overview

The Timeback SDK provides an Express middleware adapter.

Installation

npm install @timeback/sdk express

Server Setup

Create a Timeback instance:
lib/timeback.ts
import { createTimeback } from '@timeback/sdk'

export const timeback = await createTimeback({
	env: 'staging',
	api: {
		clientId: process.env.TIMEBACK_API_CLIENT_ID!,
		clientSecret: process.env.TIMEBACK_API_CLIENT_SECRET!,
	},
	identity: {
		mode: 'sso',
		clientId: process.env.AWS_COGNITO_CLIENT_ID!,
		clientSecret: process.env.AWS_COGNITO_CLIENT_SECRET!,
		redirectUri: 'http://localhost:3000/api/timeback/identity/callback',
		onCallbackSuccess: async ({ user, state, redirect }) => {
			await setSession({ id: user.id, email: user.email })
			return redirect(state?.returnTo ?? '/')
		},
		onCallbackError: ({ error, redirect }) => {
			return redirect('/?error=sso_failed')
		},
		getUser: req => getSessionFromRequest(req),
	},
})

Middleware

Add the Timeback middleware to your Express app:
server.ts
import { toExpressMiddleware } from '@timeback/sdk/express'
import express from 'express'

import { timeback } from './lib/timeback'

const app = express()

// Parse JSON bodies
app.use(express.json())

// Mount Timeback routes
app.use('/api/timeback', toExpressMiddleware(timeback))

// Your other routes...
app.get('/', (req, res) => {
	res.send('Hello World')
})

app.listen(3000, () => {
	console.log('Server running on port 3000')
})

Alternative: Mount on Router

For more control, you can mount routes on an Express Router:
server.ts
import { mountExpressRoutes } from '@timeback/sdk/express'
import express from 'express'

import { timeback } from './lib/timeback'

const app = express()
const router = express.Router()

// Mount Timeback routes on router
mountExpressRoutes(router, timeback)

// Use the router
app.use('/api/timeback', router)

Routes

The middleware handles these routes under /api/timeback:
RouteMethodPurpose
/identity/signinGETInitiates SSO flow
/identity/callbackGETHandles SSO callback
/identity/signoutGET/POSTSigns out user
/user/verifyGETVerifies user session
/user/meGETFetches user profile
/activityPOSTActivity tracking endpoint

With Frontend Framework

When using Express with a frontend framework like React:
server.ts
import path from 'path'

import { toExpressMiddleware } from '@timeback/sdk/express'
import express from 'express'

import { timeback } from './lib/timeback'

const app = express()

app.use(express.json())
app.use('/api/timeback', toExpressMiddleware(timeback))

// Serve static files from React build
app.use(express.static(path.join(__dirname, 'dist')))

// Handle client-side routing
app.get('*', (req, res) => {
	res.sendFile(path.join(__dirname, 'dist', 'index.html'))
})

app.listen(3000)

Next Steps