Skip to content

de-otio/lightning-talks

Lightning Talks

AWS CDK constructs for deploying a self-hosted Lightning Talks booking application. Teams sign up to give short talks, organizers schedule sessions, and attendees receive magic-link email invitations.

Features

  • Passwordless auth — magic-link sign-in via Amazon Cognito and SES
  • Multi-org — multiple independent organisations, each with their own series
  • Series and sessions — recurring weekly/biweekly/monthly talk series with bookable slots
  • Microsoft Teams integration — webhook notifications, bot, Entra ID SSO, Graph calendar sync, live meeting panel
  • Reactions and discussions — emoji reactions and threaded comments on talk slots
  • File uploads — speakers can attach slides or supporting materials
  • Statistics — aggregated usage reports stored as JSON in S3
  • Serverless — API Gateway HTTP API + Lambda, CloudFront + S3, DynamoDB, all managed by CDK

Architecture

Route 53 (DnsStack)
    └── ACM Certificate + WAF WebACL (CertificateStack, us-east-1)
    └── CloudFront Distribution  ──── S3 (React frontend)
            └── /auth/*, /series/*, /features  ──── API Gateway HTTP API
                                                        └── Lambda (Node.js 22)
                                                              └── DynamoDB
                                                              └── Cognito
                                                              └── SES
                                                              └── S3 (uploads)

Prerequisites

  • Node.js 22+
  • AWS CLI configured (aws configure)
  • AWS CDK CLI: npm install -g aws-cdk
  • AWS account bootstrapped: cdk bootstrap

Quick Start

Option A: Install the npm package (recommended)

npm install @yourorg/lightning-talks aws-cdk-lib constructs

Create your deployment config:

// bin/my-app.ts
import { App, RemovalPolicy } from "aws-cdk-lib";
import {
  LightningTalksDataStack,
  DnsStack,
  CertificateStack,
  LightningTalksStack,
  type EnvironmentConfig,
} from "@yourorg/lightning-talks";

const app = new App();

const config: EnvironmentConfig = {
  envName: "prod",
  appUrl: "https://talks.example.com",
  appDomain: "talks.example.com",
  parentZoneId: "Z0123456789",
  parentZoneName: "example.com",
  ses: { managed: true, sesAlertsEmail: "alerts@example.com" },
  allowedEmailDomains: "example.com",
  allowedOrigins: ["https://talks.example.com"],
  removalPolicy: RemovalPolicy.RETAIN,
  features: {
    reactions: true,
    discussions: true,
    statistics: true,
    uploads: { enabled: true, maxFileSizeMB: 50, maxFilesPerSlot: 3 },
    teams: { enabled: false, webhookUrls: [], botEndpoint: false,
             entraFederation: false, graphCalendar: false, meetingPanel: false },
  },
};

const dataStack = new LightningTalksDataStack(app, "Data", { config });
const dnsStack = new DnsStack(app, "Dns", { config });
const certStack = new CertificateStack(app, "Cert", {
  config, hostedZone: dnsStack.hostedZone, env: { region: "us-east-1" },
});
certStack.addDependency(dnsStack);
const appStack = new LightningTalksStack(app, "App", {
  config,
  certificate: certStack.certificate,
  hostedZone: dnsStack.hostedZone,
  webAclArn: certStack.webAclArn,
});
appStack.addDependency(dataStack);
appStack.addDependency(dnsStack);
appStack.addDependency(certStack);
cdk deploy --all

Option B: Clone and deploy directly

git clone https://github.com/yourorg/lightning-talks.git
cd lightning-talks
npm install
cp config/example.ts config/dev.ts
# Edit config/dev.ts with your domain and AWS zone ID
cdk deploy --all --context env=dev

Configuration Reference

Field Type Description
envName string Environment prefix for resource names (e.g. "dev", "prod")
appUrl string Full URL including protocol (e.g. "https://talks.example.com")
appDomain string Bare domain (e.g. "talks.example.com")
parentZoneId string Route 53 hosted zone ID of the parent zone
parentZoneName string Domain name of the parent zone
alertEmail string? Email for CloudWatch alarm notifications. Omit to skip alarm creation
ses ManagedSesConfig | ExternalSesConfig SES configuration (see below)
allowedOrigins string[] CORS allowed origins (must include appUrl)
allowedEmailDomains string? Comma-separated allowed email domains. Empty = allow all
removalPolicy RemovalPolicy RETAIN for prod, DESTROY for dev
features FeatureFlags Feature flags (see below)

SES Configuration

CDK-managed (recommended — CDK creates and verifies the domain identity):

ses: { managed: true, sesAlertsEmail: "alerts@example.com" }

Externally managed (bring your own verified SES identity):

ses: {
  managed: false,
  fromEmail: "noreply@example.com",
  identityDomain: "example.com",
  configSetName: "my-config-set",
}

Feature Flags

Flag Type Description
reactions boolean Emoji reactions on talk slots
discussions boolean Threaded comments on talk slots
statistics boolean Usage statistics dashboard
uploads.enabled boolean File upload support
uploads.maxFileSizeMB number Maximum upload size in MB
uploads.maxFilesPerSlot number Maximum files per talk slot
teams.enabled boolean Microsoft Teams webhook notifications
teams.botEndpoint boolean Teams bot messaging endpoint
teams.entraFederation boolean Entra ID (Azure AD) federated SSO
teams.graphCalendar boolean Microsoft Graph calendar sync
teams.meetingPanel boolean Live meeting panel WebSocket

Local Development

# Frontend dev server
cd frontend && npm install && npm run dev

# Lambda unit tests
cd lambdas && npm install && npm test

# CDK tests
npm test

# CDK synth (validates your config without deploying)
cdk synth --context env=dev

Running Tests

# CDK infrastructure tests
npm test

# Lambda handler tests
cd lambdas && npm test

# Frontend tests
cd frontend && npm test

Contributing

See CONTRIBUTING.md.

Security

To report a vulnerability, see SECURITY.md.

License

MIT

About

A simple Lambda-based tool for organizing lightning talks

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages