PreviewFile IconPreviewFile.dev

Password Protection

Learn how to secure your files with password-based access control

Password Protection

Password protection adds an additional layer of security to your shared files. Users must enter the correct password before they can view the file content.

Overview

Password protection is an optional feature that works alongside other security measures like time-limited access, download protection, and watermarks.

Key Features

  • 🔒 Secure Hashing: Passwords are hashed using bcrypt (10 rounds) before storage
  • 🔗 URL Parameter Support: Include password in URL for convenience
  • 💾 Session Caching: Browser remembers verification during active session
  • 🚫 Never Exposed: Password hashes are never returned in API responses
  • ⚡ Fast Verification: Optimized password checking for quick access

How to Use Password Protection

1. Upload with Password

When uploading a file or creating a preview link, simply add a password in the optional password field:

// Via tRPC
const result = await trpc.upload.confirm.mutate({
  tempKey: 'temp/user/abc123.pdf',
  fileName: 'confidential.pdf',
  mimeType: 'application/pdf',
  sizeBytes: 1024000,
  fileHash: 'sha256hash',
  ttlMinutes: 60,
  password: 'my-secure-password',  // Add password here
  noDownload: true,
  oneTime: false,
});

After upload, you'll receive:

  • Preview URL: https://previewfile.dev/p/abc123
  • Password: my-secure-password (shown in the upload result)

You can share these via different channels for better security:

  • Send link via email
  • Send password via SMS or messaging app

3. Access Protected Files

Recipients have three ways to access password-protected files:

Option A: Enter Password Manually (Most Secure)

  1. Visit the preview URL
  2. See password prompt
  3. Enter password
  4. Access file

Option B: Include Password in URL (Convenient)

Share the complete URL with password parameter:

https://previewfile.dev/p/abc123?pwd=my-secure-password

The password is automatically verified and the file is shown immediately.

Option C: Programmatic Access

// Access via API with password
const fileUrl = await trpc.preview.getFileUrl.query({
  shortUrl: 'abc123',
  password: 'my-secure-password',
});

Best Practices

✅ DO

  • Use strong passwords: Combine letters, numbers, and symbols
  • Unique passwords: Different password for each file
  • Separate channels: Send link and password via different methods
  • Temporary passwords: Use time-limited passwords for one-time shares
  • Document expiry: Combine with TTL for automatic cleanup

❌ DON'T

  • Reuse passwords: Don't use the same password across multiple files
  • Weak passwords: Avoid simple passwords like "123456" or "password"
  • Public sharing: Don't share password-protected links in public forums
  • Long-term storage: Don't rely on password alone for long-term security

Security Considerations

Password Storage

  • Passwords are hashed using bcrypt with 10 rounds
  • Original passwords are never stored in the database
  • Password hashes cannot be reversed to reveal the original password

Brute Force Protection

While bcrypt provides computational hardness, consider these additional measures:

  • Use one-time links for highly sensitive files
  • Combine with short TTL (e.g., 15-30 minutes)
  • Use strong passwords (12+ characters)
  • Consider using password managers to generate secure passwords

Session Management

  • Verified passwords are stored in browser sessionStorage
  • Sessions are cleared when the browser tab is closed
  • Re-verification required after session expires or tab closes

Examples

Example 1: Client Deliverable

// Create password-protected deliverable
const preview = await trpc.upload.confirm.mutate({
  ...fileData,
  password: 'ClientReview2024!',
  ttlMinutes: 1440,  // 24 hours
  watermark: 'Client Review - Confidential',
  noDownload: false,  // Allow download
});

// Share via email
const email = {
  to: '[email protected]',
  subject: 'Your deliverable is ready',
  body: `
    Your files are ready for review:
    Link: ${preview.previewUrl}
    Password: ClientReview2024!
    
    This link expires in 24 hours.
  `,
};

Example 2: Temporary Document Share

// Ultra-secure temporary share
const preview = await trpc.upload.confirm.mutate({
  ...fileData,
  password: generateSecurePassword(),  // Use strong random password
  ttlMinutes: 15,      // Short expiry
  oneTime: true,       // Single use
  noDownload: true,    // View only
});

// Send via different channels
sendEmail(user.email, preview.previewUrl);
sendSMS(user.phone, password);

Example 3: Team Collaboration

// Shared project file
const preview = await trpc.upload.confirm.mutate({
  ...fileData,
  password: 'TeamProject2024',  // Shared team password
  ttlMinutes: 10080,  // 7 days
  watermark: `${user.name} - ${new Date().toISOString()}`,
});

// Share in team channel with password
postToSlack(`
  📄 New project file: ${preview.previewUrl}
  🔒 Password: TeamProject2024
`);

API Reference

Upload with Password

interface ConfirmUploadInput {
  tempKey: string;
  fileName: string;
  mimeType: string;
  sizeBytes: number;
  fileHash: string;
  ttlMinutes?: number;
  watermark?: string;
  noDownload?: boolean;
  oneTime?: boolean;
  password?: string;  // Optional password (1-100 characters)
}

Verify Password

// Manually verify password
const result = await trpc.preview.verifyPassword.mutate({
  shortUrl: 'abc123',
  password: 'user-entered-password',
});
// Returns: { success: true }
// Throws: TRPCError with code 'UNAUTHORIZED' if password is invalid

Get File URL with Password

const fileUrl = await trpc.preview.getFileUrl.query({
  shortUrl: 'abc123',
  password: 'my-password',  // Required if file is password-protected
});
// Returns: { url: 'presigned-url', type: 's3' | 'direct', expiresIn?: number }

Troubleshooting

Password Not Working

  1. Check for typos: Passwords are case-sensitive
  2. Verify expiration: Link may have expired
  3. Check one-time status: Link may have been already used
  4. Clear browser cache: Old session data may be cached

Password Field Not Showing

  1. Password protection is optional - leave blank for public access
  2. Password field appears in upload configuration panel
  3. Check that you're using the latest version of the app

Next Steps

On this page