Skip to contents

Introduction

artauth provides authentication and lead capture services for the Artalytics platform. The package supports two primary use cases:

  1. Lead Capture - Artist waiting list management and whitepaper download tracking
  2. Security Utilities - Cryptographic functions for the authentication system

This guide walks you through the essential workflows to get started with artauth.

What is artauth?

artauth is the authentication and lead capture layer for the Artalytics platform. It manages:

  • Artist Waiting List: Capture and process pilot program applications
  • Whitepaper Tracking: Monitor investor and artist engagement with due diligence materials
  • Security Utilities: Token generation, hashing, and email validation for the authentication system

Package Hierarchy

appPlatform / mod* packages (application layer)
        |
    artutils (data access layer)
        |
    artauth (authentication layer)  ← This package
        |
    artcore (infrastructure layer)

artauth depends on artcore for database connectivity and rdstools for logging. It provides services used by application-layer packages and Shiny modules.

Installation

# Install from GitHub (requires GITHUB_PAT)
pak::pkg_install("artalytics/artauth")

library(artauth)

Configuration

artauth uses artcore for database connectivity. Configure the marketing database connection:

# Set in .Renviron or environment
Sys.setenv(
  ART_PGHOST_SITE = "artalytics-leads-do-user-16793376-0.d.db.ondigitalocean.com",
  ART_PGPORT_SITE = "25060",
  ART_PGUSER_SITE = "shiny",
  ART_PGPASS_SITE = "your-password",
  ART_PGDATA_SITE = "marketing"
)

Verify the connection:

cn <- artcore::dbc("artsite")
artcore::dbd(cn)

Artist Waiting List Workflow

The waiting list manages artist applications for the Artalytics pilot program. Artists progress through a defined status workflow.

Status Workflow

pending → reviewing → invited → converted
                   ↘ rejected
  • pending: Initial state after signup
  • reviewing: Under active consideration
  • invited: Approved, invitation sent
  • converted: Account created
  • rejected: Application declined

A Complete Workflow: Processing Artist Applications

Step 1: Capture Artist Signup

When an artist submits an application through your landing page or Shiny form:

waitlist_id <- create_waitlist_entry(
  email = "artist@example.com",
  full_name = "Jane Artist",
  phone = "+1-555-0100",
  specialties = "Digital Photography, NFT Art",
  url_instagram = "https://instagram.com/janeartist",
  url_portfolio = "https://janeartist.com",
  url_nft = "https://opensea.io/janeartist",
  message = "Excited to join the platform!",
  source = "landing_page"
)

print(waitlist_id)
# Returns: "550e8400-e29b-41d4-a716-446655440000"

Only email and full_name are required. All other fields are optional but help during the review process.

Step 2: Review Applications

Retrieve pending applications for admin review:

# Get all pending applications (oldest first for FIFO processing)
pending <- get_pending_waitlist()
print(nrow(pending))

# Filter by specific status
reviewing <- get_pending_waitlist(status = "reviewing")

# Get recently invited artists
invited <- get_pending_waitlist(status = "invited", limit = 50)

Look up a specific application:

entry <- get_waitlist_entry(waitlist_id)
print(entry$full_name)
print(entry$status)
print(entry$specialties)

Step 3: Update Application Status

Move applications through the review workflow:

# Start reviewing
update_waitlist_status(waitlist_id, status = "reviewing")

# Approve and invite
update_waitlist_status(waitlist_id, status = "invited")
# invited_at timestamp is automatically set

# Or decline
update_waitlist_status(waitlist_id, status = "rejected")

Step 4: Convert to User Account

Graduate approved artists to full platform accounts:

user_id <- convert_waitlist_to_user(
  waitlist_id = waitlist_id,
  send_invite_email = TRUE
)

print(user_id)

The entry status is automatically updated to “converted”.

Note: The convert_waitlist_to_user() function currently generates a placeholder UUID. Full user account creation will be implemented when the authentication system is complete.

Whitepaper Download Tracking

Track whitepaper downloads to measure investor and artist interest.

A Complete Workflow: Tracking Investor Engagement

Step 1: Log Downloads

Record downloads from your website:

download_id <- log_whitepaper_download(
  email = "partner@vc.com",
  user_type = "investor",
  ip_address = request$REMOTE_ADDR,
  user_agent = request$HTTP_USER_AGENT
)

User types: - "investor": Potential investors accessing due diligence materials - "artist": Artists interested in the platform - "other": Press, researchers, general interest (default)

Step 2: Check Prior Engagement

Personalize the experience based on engagement history:

if (has_downloaded_whitepaper(email)) {
  message("Welcome back! Here's the latest version.")
} else {
  message("Enter your email to download the whitepaper.")
}

Step 3: Review Download History

Look up all downloads by email:

downloads <- get_downloads_by_email("partner@vc.com")
print(nrow(downloads))
print(downloads$downloaded_at[1])

Step 4: Monitor Recent Activity

Get real-time download activity:

# Latest 20 downloads
recent <- get_recent_downloads(limit = 20)

# Recent investor downloads for sales follow-up
investor_leads <- get_recent_downloads(
  limit = 50,
  user_type = "investor"
)

Step 5: Generate Analytics

Get aggregate statistics:

# All-time statistics
stats <- get_whitepaper_stats()
print(stats$total_downloads)
print(stats$unique_emails)
print(stats$by_user_type)
print(stats$authenticated)
print(stats$anonymous)

# Statistics for a specific period
monthly_stats <- get_whitepaper_stats(
  start_date = as.Date("2024-11-01"),
  end_date = as.Date("2024-11-30")
)

Security Utilities

Cryptographic functions for the authentication system.

Token Generation and Hashing

Generate secure random tokens for magic links:

# 32-byte token (64 hex characters)
token <- generate_secure_token(32)
print(nchar(token))  # 64

# Hash before database storage
hashed <- hash_token(token)

# Store hashed in database
# Send original token to user via email
# Later, verify by hashing received token and comparing

This ensures tokens remain secret even if the database is compromised.

Email Validation

Validate email format before database insertion:

is_valid_email("user@example.com")  # TRUE
is_valid_email("not-an-email")      # FALSE
is_valid_email("user@domain")       # FALSE (missing TLD)

Connection Management

For batch operations, reuse database connections to avoid overhead:

# Get a single connection for multiple operations
cn <- artcore::dbc("artsite")

tryCatch({
  # Multiple operations with same connection
  pending <- get_pending_waitlist(cn = cn)

  for (id in pending$id[1:5]) {
    update_waitlist_status(id, status = "reviewing", cn = cn)
  }
}, finally = {
  # Always disconnect
  artcore::dbd(cn)
})

Error Handling

Duplicate Email Handling

The waiting list enforces unique emails:

tryCatch({
  create_waitlist_entry(
    email = "existing@example.com",
    full_name = "Test User"
  )
}, warning = function(w) {
  if (grepl("already exists", w$message)) {
    # Email already in waiting list - get existing entry
    message("Email already registered")
  }
})

TBD: Authentication System

The following features are planned for future implementation:

  • Magic link generation and verification
  • User account management (CRUD)
  • Role-based access control (artist, collector, investor, admin)
  • Session management
  • Integration with artsend for email delivery

Next Steps

For questions and issues, visit the GitHub repository.