@mdguggenbichler/slugbase-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/backend/dist/app-factory.d.ts +17 -0
- package/backend/dist/app-factory.d.ts.map +1 -0
- package/backend/dist/app-factory.js +106 -0
- package/backend/dist/app-factory.js.map +1 -0
- package/backend/dist/auth/authorization.d.ts +25 -0
- package/backend/dist/auth/authorization.d.ts.map +1 -0
- package/backend/dist/auth/authorization.js +100 -0
- package/backend/dist/auth/authorization.js.map +1 -0
- package/backend/dist/auth/jwt.d.ts +5 -0
- package/backend/dist/auth/jwt.d.ts.map +1 -0
- package/backend/dist/auth/jwt.js +34 -0
- package/backend/dist/auth/jwt.js.map +1 -0
- package/backend/dist/auth/oidc.d.ts +4 -0
- package/backend/dist/auth/oidc.d.ts.map +1 -0
- package/backend/dist/auth/oidc.js +201 -0
- package/backend/dist/auth/oidc.js.map +1 -0
- package/backend/dist/config/cloud-providers.d.ts +18 -0
- package/backend/dist/config/cloud-providers.d.ts.map +1 -0
- package/backend/dist/config/cloud-providers.js +60 -0
- package/backend/dist/config/cloud-providers.js.map +1 -0
- package/backend/dist/config/cookies.d.ts +17 -0
- package/backend/dist/config/cookies.d.ts.map +1 -0
- package/backend/dist/config/cookies.js +26 -0
- package/backend/dist/config/cookies.js.map +1 -0
- package/backend/dist/config/mode.d.ts +7 -0
- package/backend/dist/config/mode.d.ts.map +1 -0
- package/backend/dist/config/mode.js +7 -0
- package/backend/dist/config/mode.js.map +1 -0
- package/backend/dist/config/swagger.d.ts +2 -0
- package/backend/dist/config/swagger.d.ts.map +1 -0
- package/backend/dist/config/swagger.js +76 -0
- package/backend/dist/config/swagger.js.map +1 -0
- package/backend/dist/config.d.ts +29 -0
- package/backend/dist/config.d.ts.map +1 -0
- package/backend/dist/config.js +41 -0
- package/backend/dist/config.js.map +1 -0
- package/backend/dist/db/index.d.ts +14 -0
- package/backend/dist/db/index.d.ts.map +1 -0
- package/backend/dist/db/index.js +114 -0
- package/backend/dist/db/index.js.map +1 -0
- package/backend/dist/db/migrate-slug-nullable.d.ts +10 -0
- package/backend/dist/db/migrate-slug-nullable.d.ts.map +1 -0
- package/backend/dist/db/migrate-slug-nullable.js +87 -0
- package/backend/dist/db/migrate-slug-nullable.js.map +1 -0
- package/backend/dist/db/migrations/001_migrate_slug_nullable.d.ts +10 -0
- package/backend/dist/db/migrations/001_migrate_slug_nullable.d.ts.map +1 -0
- package/backend/dist/db/migrations/001_migrate_slug_nullable.js +103 -0
- package/backend/dist/db/migrations/001_migrate_slug_nullable.js.map +1 -0
- package/backend/dist/db/migrations/002_add_oidc_custom_endpoints.d.ts +11 -0
- package/backend/dist/db/migrations/002_add_oidc_custom_endpoints.d.ts.map +1 -0
- package/backend/dist/db/migrations/002_add_oidc_custom_endpoints.js +92 -0
- package/backend/dist/db/migrations/002_add_oidc_custom_endpoints.js.map +1 -0
- package/backend/dist/db/migrations/003_add_bookmark_features.d.ts +5 -0
- package/backend/dist/db/migrations/003_add_bookmark_features.d.ts.map +1 -0
- package/backend/dist/db/migrations/003_add_bookmark_features.js +98 -0
- package/backend/dist/db/migrations/003_add_bookmark_features.js.map +1 -0
- package/backend/dist/db/migrations/004_make_slug_globally_unique.d.ts +12 -0
- package/backend/dist/db/migrations/004_make_slug_globally_unique.d.ts.map +1 -0
- package/backend/dist/db/migrations/004_make_slug_globally_unique.js +152 -0
- package/backend/dist/db/migrations/004_make_slug_globally_unique.js.map +1 -0
- package/backend/dist/db/migrations/005_add_email_verification.d.ts +5 -0
- package/backend/dist/db/migrations/005_add_email_verification.d.ts.map +1 -0
- package/backend/dist/db/migrations/005_add_email_verification.js +102 -0
- package/backend/dist/db/migrations/005_add_email_verification.js.map +1 -0
- package/backend/dist/db/migrations/006_refresh_tokens.d.ts +9 -0
- package/backend/dist/db/migrations/006_refresh_tokens.d.ts.map +1 -0
- package/backend/dist/db/migrations/006_refresh_tokens.js +61 -0
- package/backend/dist/db/migrations/006_refresh_tokens.js.map +1 -0
- package/backend/dist/db/migrations/007_password_reset_token_hash.d.ts +10 -0
- package/backend/dist/db/migrations/007_password_reset_token_hash.d.ts.map +1 -0
- package/backend/dist/db/migrations/007_password_reset_token_hash.js +40 -0
- package/backend/dist/db/migrations/007_password_reset_token_hash.js.map +1 -0
- package/backend/dist/db/migrations/008_slug_preferences.d.ts +8 -0
- package/backend/dist/db/migrations/008_slug_preferences.d.ts.map +1 -0
- package/backend/dist/db/migrations/008_slug_preferences.js +24 -0
- package/backend/dist/db/migrations/008_slug_preferences.js.map +1 -0
- package/backend/dist/db/migrations/009_signup_email_verified.d.ts +5 -0
- package/backend/dist/db/migrations/009_signup_email_verified.d.ts.map +1 -0
- package/backend/dist/db/migrations/009_signup_email_verified.js +79 -0
- package/backend/dist/db/migrations/009_signup_email_verified.js.map +1 -0
- package/backend/dist/db/migrations/010_organizations.d.ts +5 -0
- package/backend/dist/db/migrations/010_organizations.d.ts.map +1 -0
- package/backend/dist/db/migrations/010_organizations.js +113 -0
- package/backend/dist/db/migrations/010_organizations.js.map +1 -0
- package/backend/dist/db/migrations/011_org_scoped_teams.d.ts +11 -0
- package/backend/dist/db/migrations/011_org_scoped_teams.d.ts.map +1 -0
- package/backend/dist/db/migrations/011_org_scoped_teams.js +59 -0
- package/backend/dist/db/migrations/011_org_scoped_teams.js.map +1 -0
- package/backend/dist/db/migrations/012_org_invitations_token_hash.d.ts +10 -0
- package/backend/dist/db/migrations/012_org_invitations_token_hash.d.ts.map +1 -0
- package/backend/dist/db/migrations/012_org_invitations_token_hash.js +40 -0
- package/backend/dist/db/migrations/012_org_invitations_token_hash.js.map +1 -0
- package/backend/dist/db/migrations/013_signup_verification_token_hash.d.ts +10 -0
- package/backend/dist/db/migrations/013_signup_verification_token_hash.d.ts.map +1 -0
- package/backend/dist/db/migrations/013_signup_verification_token_hash.js +39 -0
- package/backend/dist/db/migrations/013_signup_verification_token_hash.js.map +1 -0
- package/backend/dist/db/migrations/014_stats_indexes.d.ts +8 -0
- package/backend/dist/db/migrations/014_stats_indexes.d.ts.map +1 -0
- package/backend/dist/db/migrations/014_stats_indexes.js +19 -0
- package/backend/dist/db/migrations/014_stats_indexes.js.map +1 -0
- package/backend/dist/db/migrations/015_api_tokens.d.ts +9 -0
- package/backend/dist/db/migrations/015_api_tokens.d.ts.map +1 -0
- package/backend/dist/db/migrations/015_api_tokens.js +48 -0
- package/backend/dist/db/migrations/015_api_tokens.js.map +1 -0
- package/backend/dist/db/migrations/016_free_plan_grace_ends_at.d.ts +9 -0
- package/backend/dist/db/migrations/016_free_plan_grace_ends_at.d.ts.map +1 -0
- package/backend/dist/db/migrations/016_free_plan_grace_ends_at.js +50 -0
- package/backend/dist/db/migrations/016_free_plan_grace_ends_at.js.map +1 -0
- package/backend/dist/db/migrations/017_ai_suggestions.d.ts +11 -0
- package/backend/dist/db/migrations/017_ai_suggestions.d.ts.map +1 -0
- package/backend/dist/db/migrations/017_ai_suggestions.js +78 -0
- package/backend/dist/db/migrations/017_ai_suggestions.js.map +1 -0
- package/backend/dist/db/migrations/018_ai_cache_output_language.d.ts +10 -0
- package/backend/dist/db/migrations/018_ai_cache_output_language.d.ts.map +1 -0
- package/backend/dist/db/migrations/018_ai_cache_output_language.js +89 -0
- package/backend/dist/db/migrations/018_ai_cache_output_language.js.map +1 -0
- package/backend/dist/db/migrations/019_ai_suggestion_usage.d.ts +10 -0
- package/backend/dist/db/migrations/019_ai_suggestion_usage.d.ts.map +1 -0
- package/backend/dist/db/migrations/019_ai_suggestion_usage.js +47 -0
- package/backend/dist/db/migrations/019_ai_suggestion_usage.js.map +1 -0
- package/backend/dist/db/migrations/020_tenant_scope.d.ts +5 -0
- package/backend/dist/db/migrations/020_tenant_scope.d.ts.map +1 -0
- package/backend/dist/db/migrations/020_tenant_scope.js +105 -0
- package/backend/dist/db/migrations/020_tenant_scope.js.map +1 -0
- package/backend/dist/db/migrations/_legacy_cloud_010_organizations.d.ts +5 -0
- package/backend/dist/db/migrations/_legacy_cloud_010_organizations.d.ts.map +1 -0
- package/backend/dist/db/migrations/_legacy_cloud_010_organizations.js +113 -0
- package/backend/dist/db/migrations/_legacy_cloud_010_organizations.js.map +1 -0
- package/backend/dist/db/migrations/_legacy_cloud_011_org_scoped_teams.d.ts +11 -0
- package/backend/dist/db/migrations/_legacy_cloud_011_org_scoped_teams.d.ts.map +1 -0
- package/backend/dist/db/migrations/_legacy_cloud_011_org_scoped_teams.js +59 -0
- package/backend/dist/db/migrations/_legacy_cloud_011_org_scoped_teams.js.map +1 -0
- package/backend/dist/db/migrations/_legacy_cloud_012_org_invitations_token_hash.d.ts +10 -0
- package/backend/dist/db/migrations/_legacy_cloud_012_org_invitations_token_hash.d.ts.map +1 -0
- package/backend/dist/db/migrations/_legacy_cloud_012_org_invitations_token_hash.js +40 -0
- package/backend/dist/db/migrations/_legacy_cloud_012_org_invitations_token_hash.js.map +1 -0
- package/backend/dist/db/migrations/_legacy_cloud_016_free_plan_grace_ends_at.d.ts +9 -0
- package/backend/dist/db/migrations/_legacy_cloud_016_free_plan_grace_ends_at.d.ts.map +1 -0
- package/backend/dist/db/migrations/_legacy_cloud_016_free_plan_grace_ends_at.js +50 -0
- package/backend/dist/db/migrations/_legacy_cloud_016_free_plan_grace_ends_at.js.map +1 -0
- package/backend/dist/db/migrations/_legacy_cloud_017_ai_suggestions.d.ts +11 -0
- package/backend/dist/db/migrations/_legacy_cloud_017_ai_suggestions.d.ts.map +1 -0
- package/backend/dist/db/migrations/_legacy_cloud_017_ai_suggestions.js +78 -0
- package/backend/dist/db/migrations/_legacy_cloud_017_ai_suggestions.js.map +1 -0
- package/backend/dist/db/migrations/index.d.ts +22 -0
- package/backend/dist/db/migrations/index.d.ts.map +1 -0
- package/backend/dist/db/migrations/index.js +194 -0
- package/backend/dist/db/migrations/index.js.map +1 -0
- package/backend/dist/db/pool.d.ts +13 -0
- package/backend/dist/db/pool.d.ts.map +1 -0
- package/backend/dist/db/pool.js +41 -0
- package/backend/dist/db/pool.js.map +1 -0
- package/backend/dist/db/seed-data.d.ts +66 -0
- package/backend/dist/db/seed-data.d.ts.map +1 -0
- package/backend/dist/db/seed-data.js +394 -0
- package/backend/dist/db/seed-data.js.map +1 -0
- package/backend/dist/db/seed.d.ts +19 -0
- package/backend/dist/db/seed.d.ts.map +1 -0
- package/backend/dist/db/seed.js +406 -0
- package/backend/dist/db/seed.js.map +1 -0
- package/backend/dist/index.d.ts +3 -0
- package/backend/dist/index.d.ts.map +1 -0
- package/backend/dist/index.js +64 -0
- package/backend/dist/index.js.map +1 -0
- package/backend/dist/instrument.d.ts +2 -0
- package/backend/dist/instrument.d.ts.map +1 -0
- package/backend/dist/instrument.js +16 -0
- package/backend/dist/instrument.js.map +1 -0
- package/backend/dist/load-env.d.ts +2 -0
- package/backend/dist/load-env.d.ts.map +1 -0
- package/backend/dist/load-env.js +33 -0
- package/backend/dist/load-env.js.map +1 -0
- package/backend/dist/middleware/auth.d.ts +23 -0
- package/backend/dist/middleware/auth.d.ts.map +1 -0
- package/backend/dist/middleware/auth.js +69 -0
- package/backend/dist/middleware/auth.js.map +1 -0
- package/backend/dist/middleware/error-handler.d.ts +11 -0
- package/backend/dist/middleware/error-handler.d.ts.map +1 -0
- package/backend/dist/middleware/error-handler.js +40 -0
- package/backend/dist/middleware/error-handler.js.map +1 -0
- package/backend/dist/middleware/security.d.ts +26 -0
- package/backend/dist/middleware/security.d.ts.map +1 -0
- package/backend/dist/middleware/security.js +162 -0
- package/backend/dist/middleware/security.js.map +1 -0
- package/backend/dist/middleware/stats-auth.d.ts +7 -0
- package/backend/dist/middleware/stats-auth.d.ts.map +1 -0
- package/backend/dist/middleware/stats-auth.js +20 -0
- package/backend/dist/middleware/stats-auth.js.map +1 -0
- package/backend/dist/middleware/tenant.d.ts +3 -0
- package/backend/dist/middleware/tenant.d.ts.map +1 -0
- package/backend/dist/middleware/tenant.js +13 -0
- package/backend/dist/middleware/tenant.js.map +1 -0
- package/backend/dist/register-routes.d.ts +12 -0
- package/backend/dist/register-routes.d.ts.map +1 -0
- package/backend/dist/register-routes.js +59 -0
- package/backend/dist/register-routes.js.map +1 -0
- package/backend/dist/routes/admin/demo-reset.d.ts +8 -0
- package/backend/dist/routes/admin/demo-reset.d.ts.map +1 -0
- package/backend/dist/routes/admin/demo-reset.js +66 -0
- package/backend/dist/routes/admin/demo-reset.js.map +1 -0
- package/backend/dist/routes/admin/settings.d.ts +3 -0
- package/backend/dist/routes/admin/settings.d.ts.map +1 -0
- package/backend/dist/routes/admin/settings.js +452 -0
- package/backend/dist/routes/admin/settings.js.map +1 -0
- package/backend/dist/routes/admin/stats.d.ts +7 -0
- package/backend/dist/routes/admin/stats.d.ts.map +1 -0
- package/backend/dist/routes/admin/stats.js +66 -0
- package/backend/dist/routes/admin/stats.js.map +1 -0
- package/backend/dist/routes/admin/teams.d.ts +3 -0
- package/backend/dist/routes/admin/teams.d.ts.map +1 -0
- package/backend/dist/routes/admin/teams.js +509 -0
- package/backend/dist/routes/admin/teams.js.map +1 -0
- package/backend/dist/routes/admin/users.d.ts +3 -0
- package/backend/dist/routes/admin/users.d.ts.map +1 -0
- package/backend/dist/routes/admin/users.js +525 -0
- package/backend/dist/routes/admin/users.js.map +1 -0
- package/backend/dist/routes/auth.d.ts +3 -0
- package/backend/dist/routes/auth.d.ts.map +1 -0
- package/backend/dist/routes/auth.js +992 -0
- package/backend/dist/routes/auth.js.map +1 -0
- package/backend/dist/routes/billing.d.ts +8 -0
- package/backend/dist/routes/billing.d.ts.map +1 -0
- package/backend/dist/routes/billing.js +481 -0
- package/backend/dist/routes/billing.js.map +1 -0
- package/backend/dist/routes/bookmarks.d.ts +3 -0
- package/backend/dist/routes/bookmarks.d.ts.map +1 -0
- package/backend/dist/routes/bookmarks.js +1593 -0
- package/backend/dist/routes/bookmarks.js.map +1 -0
- package/backend/dist/routes/config.d.ts +7 -0
- package/backend/dist/routes/config.d.ts.map +1 -0
- package/backend/dist/routes/config.js +52 -0
- package/backend/dist/routes/config.js.map +1 -0
- package/backend/dist/routes/contact.d.ts +9 -0
- package/backend/dist/routes/contact.d.ts.map +1 -0
- package/backend/dist/routes/contact.js +99 -0
- package/backend/dist/routes/contact.js.map +1 -0
- package/backend/dist/routes/csrf.d.ts +3 -0
- package/backend/dist/routes/csrf.d.ts.map +1 -0
- package/backend/dist/routes/csrf.js +39 -0
- package/backend/dist/routes/csrf.js.map +1 -0
- package/backend/dist/routes/dashboard.d.ts +3 -0
- package/backend/dist/routes/dashboard.d.ts.map +1 -0
- package/backend/dist/routes/dashboard.js +212 -0
- package/backend/dist/routes/dashboard.js.map +1 -0
- package/backend/dist/routes/email-verification.d.ts +3 -0
- package/backend/dist/routes/email-verification.d.ts.map +1 -0
- package/backend/dist/routes/email-verification.js +124 -0
- package/backend/dist/routes/email-verification.js.map +1 -0
- package/backend/dist/routes/folders.d.ts +3 -0
- package/backend/dist/routes/folders.d.ts.map +1 -0
- package/backend/dist/routes/folders.js +524 -0
- package/backend/dist/routes/folders.js.map +1 -0
- package/backend/dist/routes/go-helpers.d.ts +18 -0
- package/backend/dist/routes/go-helpers.d.ts.map +1 -0
- package/backend/dist/routes/go-helpers.js +64 -0
- package/backend/dist/routes/go-helpers.js.map +1 -0
- package/backend/dist/routes/go.d.ts +23 -0
- package/backend/dist/routes/go.d.ts.map +1 -0
- package/backend/dist/routes/go.js +361 -0
- package/backend/dist/routes/go.js.map +1 -0
- package/backend/dist/routes/health.d.ts +6 -0
- package/backend/dist/routes/health.d.ts.map +1 -0
- package/backend/dist/routes/health.js +79 -0
- package/backend/dist/routes/health.js.map +1 -0
- package/backend/dist/routes/invitations.d.ts +3 -0
- package/backend/dist/routes/invitations.d.ts.map +1 -0
- package/backend/dist/routes/invitations.js +172 -0
- package/backend/dist/routes/invitations.js.map +1 -0
- package/backend/dist/routes/oidc-providers.d.ts +3 -0
- package/backend/dist/routes/oidc-providers.d.ts.map +1 -0
- package/backend/dist/routes/oidc-providers.js +495 -0
- package/backend/dist/routes/oidc-providers.js.map +1 -0
- package/backend/dist/routes/organizations.d.ts +3 -0
- package/backend/dist/routes/organizations.d.ts.map +1 -0
- package/backend/dist/routes/organizations.js +538 -0
- package/backend/dist/routes/organizations.js.map +1 -0
- package/backend/dist/routes/password-reset.d.ts +3 -0
- package/backend/dist/routes/password-reset.d.ts.map +1 -0
- package/backend/dist/routes/password-reset.js +212 -0
- package/backend/dist/routes/password-reset.js.map +1 -0
- package/backend/dist/routes/redirect.d.ts +3 -0
- package/backend/dist/routes/redirect.d.ts.map +1 -0
- package/backend/dist/routes/redirect.js +124 -0
- package/backend/dist/routes/redirect.js.map +1 -0
- package/backend/dist/routes/tags.d.ts +3 -0
- package/backend/dist/routes/tags.d.ts.map +1 -0
- package/backend/dist/routes/tags.js +302 -0
- package/backend/dist/routes/tags.js.map +1 -0
- package/backend/dist/routes/teams.d.ts +3 -0
- package/backend/dist/routes/teams.d.ts.map +1 -0
- package/backend/dist/routes/teams.js +60 -0
- package/backend/dist/routes/teams.js.map +1 -0
- package/backend/dist/routes/tokens.d.ts +3 -0
- package/backend/dist/routes/tokens.d.ts.map +1 -0
- package/backend/dist/routes/tokens.js +157 -0
- package/backend/dist/routes/tokens.js.map +1 -0
- package/backend/dist/routes/users.d.ts +3 -0
- package/backend/dist/routes/users.d.ts.map +1 -0
- package/backend/dist/routes/users.js +199 -0
- package/backend/dist/routes/users.js.map +1 -0
- package/backend/dist/services/ai-suggestions.d.ts +29 -0
- package/backend/dist/services/ai-suggestions.d.ts.map +1 -0
- package/backend/dist/services/ai-suggestions.js +163 -0
- package/backend/dist/services/ai-suggestions.js.map +1 -0
- package/backend/dist/services/api-tokens.d.ts +66 -0
- package/backend/dist/services/api-tokens.d.ts.map +1 -0
- package/backend/dist/services/api-tokens.js +129 -0
- package/backend/dist/services/api-tokens.js.map +1 -0
- package/backend/dist/services/fetch-page-metadata.d.ts +15 -0
- package/backend/dist/services/fetch-page-metadata.d.ts.map +1 -0
- package/backend/dist/services/fetch-page-metadata.js +205 -0
- package/backend/dist/services/fetch-page-metadata.js.map +1 -0
- package/backend/dist/services/stats.d.ts +73 -0
- package/backend/dist/services/stats.d.ts.map +1 -0
- package/backend/dist/services/stats.js +145 -0
- package/backend/dist/services/stats.js.map +1 -0
- package/backend/dist/types/oidc-provider.d.ts +17 -0
- package/backend/dist/types/oidc-provider.d.ts.map +1 -0
- package/backend/dist/types/oidc-provider.js +2 -0
- package/backend/dist/types/oidc-provider.js.map +1 -0
- package/backend/dist/types.d.ts +86 -0
- package/backend/dist/types.d.ts.map +1 -0
- package/backend/dist/types.js +2 -0
- package/backend/dist/types.js.map +1 -0
- package/backend/dist/utils/ai-feature.d.ts +23 -0
- package/backend/dist/utils/ai-feature.d.ts.map +1 -0
- package/backend/dist/utils/ai-feature.js +62 -0
- package/backend/dist/utils/ai-feature.js.map +1 -0
- package/backend/dist/utils/email.d.ts +40 -0
- package/backend/dist/utils/email.d.ts.map +1 -0
- package/backend/dist/utils/email.js +456 -0
- package/backend/dist/utils/email.js.map +1 -0
- package/backend/dist/utils/encryption.d.ts +18 -0
- package/backend/dist/utils/encryption.d.ts.map +1 -0
- package/backend/dist/utils/encryption.js +95 -0
- package/backend/dist/utils/encryption.js.map +1 -0
- package/backend/dist/utils/env-validation.d.ts +6 -0
- package/backend/dist/utils/env-validation.d.ts.map +1 -0
- package/backend/dist/utils/env-validation.js +51 -0
- package/backend/dist/utils/env-validation.js.map +1 -0
- package/backend/dist/utils/jwt.d.ts +20 -0
- package/backend/dist/utils/jwt.d.ts.map +1 -0
- package/backend/dist/utils/jwt.js +48 -0
- package/backend/dist/utils/jwt.js.map +1 -0
- package/backend/dist/utils/org-cleanup.d.ts +6 -0
- package/backend/dist/utils/org-cleanup.d.ts.map +1 -0
- package/backend/dist/utils/org-cleanup.js +37 -0
- package/backend/dist/utils/org-cleanup.js.map +1 -0
- package/backend/dist/utils/organizations.d.ts +12 -0
- package/backend/dist/utils/organizations.d.ts.map +1 -0
- package/backend/dist/utils/organizations.js +24 -0
- package/backend/dist/utils/organizations.js.map +1 -0
- package/backend/dist/utils/plan-errors.d.ts +18 -0
- package/backend/dist/utils/plan-errors.d.ts.map +1 -0
- package/backend/dist/utils/plan-errors.js +21 -0
- package/backend/dist/utils/plan-errors.js.map +1 -0
- package/backend/dist/utils/refresh-token.d.ts +31 -0
- package/backend/dist/utils/refresh-token.d.ts.map +1 -0
- package/backend/dist/utils/refresh-token.js +63 -0
- package/backend/dist/utils/refresh-token.js.map +1 -0
- package/backend/dist/utils/session-store.d.ts +46 -0
- package/backend/dist/utils/session-store.d.ts.map +1 -0
- package/backend/dist/utils/session-store.js +222 -0
- package/backend/dist/utils/session-store.js.map +1 -0
- package/backend/dist/utils/tenant.d.ts +5 -0
- package/backend/dist/utils/tenant.d.ts.map +1 -0
- package/backend/dist/utils/tenant.js +12 -0
- package/backend/dist/utils/tenant.js.map +1 -0
- package/backend/dist/utils/user-key.d.ts +24 -0
- package/backend/dist/utils/user-key.d.ts.map +1 -0
- package/backend/dist/utils/user-key.js +116 -0
- package/backend/dist/utils/user-key.js.map +1 -0
- package/backend/dist/utils/validation.d.ts +91 -0
- package/backend/dist/utils/validation.d.ts.map +1 -0
- package/backend/dist/utils/validation.js +337 -0
- package/backend/dist/utils/validation.js.map +1 -0
- package/backend/index.js +15 -0
- package/frontend/index.js +5 -0
- package/frontend/index.tsx +7 -0
- package/package.json +16 -0
- package/types/index.js +4 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"002_add_oidc_custom_endpoints.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/002_add_oidc_custom_endpoints.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,eAAO,MAAM,WAAW,kCAAkC,CAAC;AAC3D,eAAO,MAAM,aAAa,oCAAoC,CAAC;AAE/D,wBAAsB,EAAE,kBA8CvB;AAED,wBAAsB,IAAI,kBAuCzB"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration: Add custom OIDC endpoint fields
|
|
3
|
+
* Date: 2026-01-12
|
|
4
|
+
* Description: Adds optional custom endpoint fields (authorization_url, token_url, userinfo_url) to oidc_providers table
|
|
5
|
+
* to allow providers with non-standard endpoint paths
|
|
6
|
+
*/
|
|
7
|
+
import { execute } from '../index.js';
|
|
8
|
+
export const migrationId = '002_add_oidc_custom_endpoints';
|
|
9
|
+
export const migrationName = 'Add custom OIDC endpoint fields';
|
|
10
|
+
export async function up() {
|
|
11
|
+
const DB_TYPE = process.env.DB_TYPE || 'sqlite';
|
|
12
|
+
if (DB_TYPE === 'postgresql') {
|
|
13
|
+
// PostgreSQL: Add columns
|
|
14
|
+
await execute('ALTER TABLE oidc_providers ADD COLUMN IF NOT EXISTS authorization_url TEXT', []);
|
|
15
|
+
await execute('ALTER TABLE oidc_providers ADD COLUMN IF NOT EXISTS token_url TEXT', []);
|
|
16
|
+
await execute('ALTER TABLE oidc_providers ADD COLUMN IF NOT EXISTS userinfo_url TEXT', []);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
// SQLite: Need to recreate table
|
|
20
|
+
// Create new table with new columns
|
|
21
|
+
await execute(`
|
|
22
|
+
CREATE TABLE IF NOT EXISTS oidc_providers_new (
|
|
23
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
24
|
+
provider_key VARCHAR(255) UNIQUE NOT NULL,
|
|
25
|
+
client_id TEXT NOT NULL,
|
|
26
|
+
client_secret TEXT NOT NULL,
|
|
27
|
+
issuer_url TEXT NOT NULL,
|
|
28
|
+
authorization_url TEXT,
|
|
29
|
+
token_url TEXT,
|
|
30
|
+
userinfo_url TEXT,
|
|
31
|
+
scopes TEXT NOT NULL,
|
|
32
|
+
auto_create_users BOOLEAN DEFAULT TRUE,
|
|
33
|
+
default_role VARCHAR(50) DEFAULT 'user',
|
|
34
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
35
|
+
)
|
|
36
|
+
`, []);
|
|
37
|
+
// Copy data from old table
|
|
38
|
+
await execute(`
|
|
39
|
+
INSERT INTO oidc_providers_new (
|
|
40
|
+
id, provider_key, client_id, client_secret, issuer_url,
|
|
41
|
+
scopes, auto_create_users, default_role, created_at
|
|
42
|
+
)
|
|
43
|
+
SELECT
|
|
44
|
+
id, provider_key, client_id, client_secret, issuer_url,
|
|
45
|
+
scopes, auto_create_users, default_role, created_at
|
|
46
|
+
FROM oidc_providers
|
|
47
|
+
`, []);
|
|
48
|
+
// Drop old table
|
|
49
|
+
await execute('DROP TABLE oidc_providers', []);
|
|
50
|
+
// Rename new table
|
|
51
|
+
await execute('ALTER TABLE oidc_providers_new RENAME TO oidc_providers', []);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export async function down() {
|
|
55
|
+
const DB_TYPE = process.env.DB_TYPE || 'sqlite';
|
|
56
|
+
if (DB_TYPE === 'postgresql') {
|
|
57
|
+
// PostgreSQL: Drop columns
|
|
58
|
+
await execute('ALTER TABLE oidc_providers DROP COLUMN IF EXISTS authorization_url', []);
|
|
59
|
+
await execute('ALTER TABLE oidc_providers DROP COLUMN IF EXISTS token_url', []);
|
|
60
|
+
await execute('ALTER TABLE oidc_providers DROP COLUMN IF EXISTS userinfo_url', []);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// SQLite: Need to recreate table without new columns
|
|
64
|
+
await execute(`
|
|
65
|
+
CREATE TABLE IF NOT EXISTS oidc_providers_new (
|
|
66
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
67
|
+
provider_key VARCHAR(255) UNIQUE NOT NULL,
|
|
68
|
+
client_id TEXT NOT NULL,
|
|
69
|
+
client_secret TEXT NOT NULL,
|
|
70
|
+
issuer_url TEXT NOT NULL,
|
|
71
|
+
scopes TEXT NOT NULL,
|
|
72
|
+
auto_create_users BOOLEAN DEFAULT TRUE,
|
|
73
|
+
default_role VARCHAR(50) DEFAULT 'user',
|
|
74
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
75
|
+
)
|
|
76
|
+
`, []);
|
|
77
|
+
// Copy data (excluding new columns)
|
|
78
|
+
await execute(`
|
|
79
|
+
INSERT INTO oidc_providers_new (
|
|
80
|
+
id, provider_key, client_id, client_secret, issuer_url,
|
|
81
|
+
scopes, auto_create_users, default_role, created_at
|
|
82
|
+
)
|
|
83
|
+
SELECT
|
|
84
|
+
id, provider_key, client_id, client_secret, issuer_url,
|
|
85
|
+
scopes, auto_create_users, default_role, created_at
|
|
86
|
+
FROM oidc_providers
|
|
87
|
+
`, []);
|
|
88
|
+
await execute('DROP TABLE oidc_providers', []);
|
|
89
|
+
await execute('ALTER TABLE oidc_providers_new RENAME TO oidc_providers', []);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=002_add_oidc_custom_endpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"002_add_oidc_custom_endpoints.js","sourceRoot":"","sources":["../../../src/db/migrations/002_add_oidc_custom_endpoints.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,MAAM,CAAC,MAAM,WAAW,GAAG,+BAA+B,CAAC;AAC3D,MAAM,CAAC,MAAM,aAAa,GAAG,iCAAiC,CAAC;AAE/D,MAAM,CAAC,KAAK,UAAU,EAAE;IACtB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,QAAQ,CAAC;IAEhD,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;QAC7B,0BAA0B;QAC1B,MAAM,OAAO,CAAC,4EAA4E,EAAE,EAAE,CAAC,CAAC;QAChG,MAAM,OAAO,CAAC,oEAAoE,EAAE,EAAE,CAAC,CAAC;QACxF,MAAM,OAAO,CAAC,uEAAuE,EAAE,EAAE,CAAC,CAAC;IAC7F,CAAC;SAAM,CAAC;QACN,iCAAiC;QACjC,oCAAoC;QACpC,MAAM,OAAO,CAAC;;;;;;;;;;;;;;;KAeb,EAAE,EAAE,CAAC,CAAC;QAEP,2BAA2B;QAC3B,MAAM,OAAO,CAAC;;;;;;;;;KASb,EAAE,EAAE,CAAC,CAAC;QAEP,iBAAiB;QACjB,MAAM,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;QAE/C,mBAAmB;QACnB,MAAM,OAAO,CAAC,yDAAyD,EAAE,EAAE,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,QAAQ,CAAC;IAEhD,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;QAC7B,2BAA2B;QAC3B,MAAM,OAAO,CAAC,oEAAoE,EAAE,EAAE,CAAC,CAAC;QACxF,MAAM,OAAO,CAAC,4DAA4D,EAAE,EAAE,CAAC,CAAC;QAChF,MAAM,OAAO,CAAC,+DAA+D,EAAE,EAAE,CAAC,CAAC;IACrF,CAAC;SAAM,CAAC;QACN,qDAAqD;QACrD,MAAM,OAAO,CAAC;;;;;;;;;;;;KAYb,EAAE,EAAE,CAAC,CAAC;QAEP,oCAAoC;QACpC,MAAM,OAAO,CAAC;;;;;;;;;KASb,EAAE,EAAE,CAAC,CAAC;QAEP,MAAM,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;QAC/C,MAAM,OAAO,CAAC,yDAAyD,EAAE,EAAE,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const migrationId = "003_add_bookmark_features";
|
|
2
|
+
export declare const migrationName = "Add pinned, access_count, and last_accessed_at fields to bookmarks";
|
|
3
|
+
export declare function up(): Promise<void>;
|
|
4
|
+
export declare function down(): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=003_add_bookmark_features.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"003_add_bookmark_features.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/003_add_bookmark_features.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,8BAA8B,CAAC;AACvD,eAAO,MAAM,aAAa,uEAAuE,CAAC;AAElG,wBAAsB,EAAE,kBAuDvB;AAED,wBAAsB,IAAI,kBA6CzB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { execute } from '../index.js';
|
|
2
|
+
export const migrationId = '003_add_bookmark_features';
|
|
3
|
+
export const migrationName = 'Add pinned, access_count, and last_accessed_at fields to bookmarks';
|
|
4
|
+
export async function up() {
|
|
5
|
+
const DB_TYPE = process.env.DB_TYPE || 'sqlite';
|
|
6
|
+
if (DB_TYPE === 'postgresql') {
|
|
7
|
+
// PostgreSQL: Add columns directly
|
|
8
|
+
await execute('ALTER TABLE bookmarks ADD COLUMN IF NOT EXISTS pinned BOOLEAN DEFAULT FALSE', []);
|
|
9
|
+
await execute('ALTER TABLE bookmarks ADD COLUMN IF NOT EXISTS access_count INTEGER DEFAULT 0', []);
|
|
10
|
+
await execute('ALTER TABLE bookmarks ADD COLUMN IF NOT EXISTS last_accessed_at TIMESTAMP', []);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
// SQLite: Need to recreate table
|
|
14
|
+
// Create new table with new columns
|
|
15
|
+
await execute(`
|
|
16
|
+
CREATE TABLE IF NOT EXISTS bookmarks_new (
|
|
17
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
18
|
+
user_id VARCHAR(255) NOT NULL,
|
|
19
|
+
title TEXT NOT NULL,
|
|
20
|
+
url TEXT NOT NULL,
|
|
21
|
+
slug VARCHAR(255),
|
|
22
|
+
forwarding_enabled BOOLEAN DEFAULT FALSE,
|
|
23
|
+
pinned BOOLEAN DEFAULT FALSE,
|
|
24
|
+
access_count INTEGER DEFAULT 0,
|
|
25
|
+
last_accessed_at TIMESTAMP,
|
|
26
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
27
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
28
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
29
|
+
)
|
|
30
|
+
`, []);
|
|
31
|
+
// Copy data from old table
|
|
32
|
+
await execute(`
|
|
33
|
+
INSERT INTO bookmarks_new (
|
|
34
|
+
id, user_id, title, url, slug, forwarding_enabled,
|
|
35
|
+
pinned, access_count, last_accessed_at, created_at, updated_at
|
|
36
|
+
)
|
|
37
|
+
SELECT
|
|
38
|
+
id, user_id, title, url, slug, forwarding_enabled,
|
|
39
|
+
FALSE as pinned, 0 as access_count, NULL as last_accessed_at,
|
|
40
|
+
created_at, updated_at
|
|
41
|
+
FROM bookmarks
|
|
42
|
+
`, []);
|
|
43
|
+
// Drop old table
|
|
44
|
+
await execute('DROP TABLE bookmarks', []);
|
|
45
|
+
// Rename new table
|
|
46
|
+
await execute('ALTER TABLE bookmarks_new RENAME TO bookmarks', []);
|
|
47
|
+
// Recreate indexes
|
|
48
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_user_id ON bookmarks(user_id)', []);
|
|
49
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_slug ON bookmarks(slug)', []);
|
|
50
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_user_slug ON bookmarks(user_id, slug)', []);
|
|
51
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_pinned ON bookmarks(pinned)', []);
|
|
52
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_access_count ON bookmarks(access_count)', []);
|
|
53
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_last_accessed ON bookmarks(last_accessed_at)', []);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export async function down() {
|
|
57
|
+
const DB_TYPE = process.env.DB_TYPE || 'sqlite';
|
|
58
|
+
if (DB_TYPE === 'postgresql') {
|
|
59
|
+
// PostgreSQL: Remove columns
|
|
60
|
+
await execute('ALTER TABLE bookmarks DROP COLUMN IF EXISTS pinned', []);
|
|
61
|
+
await execute('ALTER TABLE bookmarks DROP COLUMN IF EXISTS access_count', []);
|
|
62
|
+
await execute('ALTER TABLE bookmarks DROP COLUMN IF EXISTS last_accessed_at', []);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// SQLite: Recreate table without new columns
|
|
66
|
+
await execute(`
|
|
67
|
+
CREATE TABLE IF NOT EXISTS bookmarks_old (
|
|
68
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
69
|
+
user_id VARCHAR(255) NOT NULL,
|
|
70
|
+
title TEXT NOT NULL,
|
|
71
|
+
url TEXT NOT NULL,
|
|
72
|
+
slug VARCHAR(255),
|
|
73
|
+
forwarding_enabled BOOLEAN DEFAULT FALSE,
|
|
74
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
75
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
76
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
77
|
+
)
|
|
78
|
+
`, []);
|
|
79
|
+
// Copy data (excluding new columns)
|
|
80
|
+
await execute(`
|
|
81
|
+
INSERT INTO bookmarks_old (
|
|
82
|
+
id, user_id, title, url, slug, forwarding_enabled, created_at, updated_at
|
|
83
|
+
)
|
|
84
|
+
SELECT
|
|
85
|
+
id, user_id, title, url, slug, forwarding_enabled, created_at, updated_at
|
|
86
|
+
FROM bookmarks
|
|
87
|
+
`, []);
|
|
88
|
+
// Drop new table
|
|
89
|
+
await execute('DROP TABLE bookmarks', []);
|
|
90
|
+
// Rename old table
|
|
91
|
+
await execute('ALTER TABLE bookmarks_old RENAME TO bookmarks', []);
|
|
92
|
+
// Recreate indexes
|
|
93
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_user_id ON bookmarks(user_id)', []);
|
|
94
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_slug ON bookmarks(slug)', []);
|
|
95
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_user_slug ON bookmarks(user_id, slug)', []);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=003_add_bookmark_features.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"003_add_bookmark_features.js","sourceRoot":"","sources":["../../../src/db/migrations/003_add_bookmark_features.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,MAAM,CAAC,MAAM,WAAW,GAAG,2BAA2B,CAAC;AACvD,MAAM,CAAC,MAAM,aAAa,GAAG,oEAAoE,CAAC;AAElG,MAAM,CAAC,KAAK,UAAU,EAAE;IACtB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,QAAQ,CAAC;IAEhD,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;QAC7B,mCAAmC;QACnC,MAAM,OAAO,CAAC,6EAA6E,EAAE,EAAE,CAAC,CAAC;QACjG,MAAM,OAAO,CAAC,+EAA+E,EAAE,EAAE,CAAC,CAAC;QACnG,MAAM,OAAO,CAAC,2EAA2E,EAAE,EAAE,CAAC,CAAC;IACjG,CAAC;SAAM,CAAC;QACN,iCAAiC;QACjC,oCAAoC;QACpC,MAAM,OAAO,CAAC;;;;;;;;;;;;;;;KAeb,EAAE,EAAE,CAAC,CAAC;QAEP,2BAA2B;QAC3B,MAAM,OAAO,CAAC;;;;;;;;;;KAUb,EAAE,EAAE,CAAC,CAAC;QAEP,iBAAiB;QACjB,MAAM,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;QAE1C,mBAAmB;QACnB,MAAM,OAAO,CAAC,+CAA+C,EAAE,EAAE,CAAC,CAAC;QAEnE,mBAAmB;QACnB,MAAM,OAAO,CAAC,wEAAwE,EAAE,EAAE,CAAC,CAAC;QAC5F,MAAM,OAAO,CAAC,kEAAkE,EAAE,EAAE,CAAC,CAAC;QACtF,MAAM,OAAO,CAAC,gFAAgF,EAAE,EAAE,CAAC,CAAC;QACpG,MAAM,OAAO,CAAC,sEAAsE,EAAE,EAAE,CAAC,CAAC;QAC1F,MAAM,OAAO,CAAC,kFAAkF,EAAE,EAAE,CAAC,CAAC;QACtG,MAAM,OAAO,CAAC,uFAAuF,EAAE,EAAE,CAAC,CAAC;IAC7G,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,QAAQ,CAAC;IAEhD,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;QAC7B,6BAA6B;QAC7B,MAAM,OAAO,CAAC,oDAAoD,EAAE,EAAE,CAAC,CAAC;QACxE,MAAM,OAAO,CAAC,0DAA0D,EAAE,EAAE,CAAC,CAAC;QAC9E,MAAM,OAAO,CAAC,8DAA8D,EAAE,EAAE,CAAC,CAAC;IACpF,CAAC;SAAM,CAAC;QACN,6CAA6C;QAC7C,MAAM,OAAO,CAAC;;;;;;;;;;;;KAYb,EAAE,EAAE,CAAC,CAAC;QAEP,oCAAoC;QACpC,MAAM,OAAO,CAAC;;;;;;;KAOb,EAAE,EAAE,CAAC,CAAC;QAEP,iBAAiB;QACjB,MAAM,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;QAE1C,mBAAmB;QACnB,MAAM,OAAO,CAAC,+CAA+C,EAAE,EAAE,CAAC,CAAC;QAEnE,mBAAmB;QACnB,MAAM,OAAO,CAAC,wEAAwE,EAAE,EAAE,CAAC,CAAC;QAC5F,MAAM,OAAO,CAAC,kEAAkE,EAAE,EAAE,CAAC,CAAC;QACtF,MAAM,OAAO,CAAC,gFAAgF,EAAE,EAAE,CAAC,CAAC;IACtG,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 004: Make slug globally unique
|
|
3
|
+
*
|
|
4
|
+
* Changes the UNIQUE constraint on bookmarks.slug from (user_id, slug) to just (slug)
|
|
5
|
+
* This ensures that when bookmarks are shared, slugs are unique across the entire system,
|
|
6
|
+
* allowing any user's user_key to work with shared bookmarks via forwarding.
|
|
7
|
+
*/
|
|
8
|
+
export declare const migrationId = "004";
|
|
9
|
+
export declare const migrationName = "Make slug globally unique";
|
|
10
|
+
export declare function up(): Promise<void>;
|
|
11
|
+
export declare function down(): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=004_make_slug_globally_unique.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"004_make_slug_globally_unique.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/004_make_slug_globally_unique.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,eAAO,MAAM,WAAW,QAAQ,CAAC;AACjC,eAAO,MAAM,aAAa,8BAA8B,CAAC;AAEzD,wBAAsB,EAAE,kBAgIvB;AAED,wBAAsB,IAAI,kBAmDzB"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 004: Make slug globally unique
|
|
3
|
+
*
|
|
4
|
+
* Changes the UNIQUE constraint on bookmarks.slug from (user_id, slug) to just (slug)
|
|
5
|
+
* This ensures that when bookmarks are shared, slugs are unique across the entire system,
|
|
6
|
+
* allowing any user's user_key to work with shared bookmarks via forwarding.
|
|
7
|
+
*/
|
|
8
|
+
import { execute, query } from '../index.js';
|
|
9
|
+
export const migrationId = '004';
|
|
10
|
+
export const migrationName = 'Make slug globally unique';
|
|
11
|
+
export async function up() {
|
|
12
|
+
const DB_TYPE = process.env.DB_TYPE || 'sqlite';
|
|
13
|
+
if (DB_TYPE === 'postgresql') {
|
|
14
|
+
// PostgreSQL: Drop the old unique constraint and add a new one
|
|
15
|
+
try {
|
|
16
|
+
// Drop the old unique constraint
|
|
17
|
+
await execute('ALTER TABLE bookmarks DROP CONSTRAINT IF EXISTS bookmarks_user_id_slug_key', []);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
// Constraint might not exist or have a different name, try alternative
|
|
21
|
+
try {
|
|
22
|
+
await execute('ALTER TABLE bookmarks DROP CONSTRAINT IF EXISTS bookmarks_user_id_slug_unique', []);
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
// Try to find and drop the constraint
|
|
26
|
+
const constraints = await query(`SELECT constraint_name
|
|
27
|
+
FROM information_schema.table_constraints
|
|
28
|
+
WHERE table_name = 'bookmarks'
|
|
29
|
+
AND constraint_type = 'UNIQUE'
|
|
30
|
+
AND constraint_name LIKE '%slug%'`, []);
|
|
31
|
+
for (const constraint of constraints) {
|
|
32
|
+
try {
|
|
33
|
+
await execute(`ALTER TABLE bookmarks DROP CONSTRAINT IF EXISTS ${constraint.constraint_name}`, []);
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
// Ignore errors
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Add global unique constraint on slug (NULL values are allowed and don't violate uniqueness)
|
|
42
|
+
await execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_bookmarks_slug_unique ON bookmarks (slug) WHERE slug IS NOT NULL', []);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// SQLite: Need to recreate the table
|
|
46
|
+
// First, check if there are any duplicate slugs (excluding NULL)
|
|
47
|
+
const duplicates = await query(`SELECT slug, COUNT(*) as count
|
|
48
|
+
FROM bookmarks
|
|
49
|
+
WHERE slug IS NOT NULL AND slug != ''
|
|
50
|
+
GROUP BY slug
|
|
51
|
+
HAVING COUNT(*) > 1`, []);
|
|
52
|
+
if (Array.isArray(duplicates) && duplicates.length > 0) {
|
|
53
|
+
// For duplicates, keep the oldest bookmark (by created_at) and nullify slugs for others
|
|
54
|
+
console.log(`Found ${duplicates.length} duplicate slug(s). Resolving by keeping oldest bookmark for each slug...`);
|
|
55
|
+
for (const dup of duplicates) {
|
|
56
|
+
const slug = dup.slug;
|
|
57
|
+
// Get all bookmarks with this slug, ordered by created_at
|
|
58
|
+
const bookmarksWithSlug = await query(`SELECT id, created_at FROM bookmarks
|
|
59
|
+
WHERE slug = ?
|
|
60
|
+
ORDER BY created_at ASC`, [slug]);
|
|
61
|
+
if (Array.isArray(bookmarksWithSlug) && bookmarksWithSlug.length > 1) {
|
|
62
|
+
// Keep the first one (oldest), nullify slugs for the rest
|
|
63
|
+
const toKeep = bookmarksWithSlug[0];
|
|
64
|
+
const toNullify = bookmarksWithSlug.slice(1);
|
|
65
|
+
for (const bm of toNullify) {
|
|
66
|
+
await execute(`UPDATE bookmarks SET slug = NULL, forwarding_enabled = FALSE WHERE id = ?`, [bm.id]);
|
|
67
|
+
console.log(` - Nullified slug for bookmark ${bm.id} (duplicate of ${toKeep.id})`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
console.log('Duplicate slugs resolved. Continuing migration...');
|
|
72
|
+
}
|
|
73
|
+
// Create new table with global unique constraint
|
|
74
|
+
await execute(`
|
|
75
|
+
CREATE TABLE bookmarks_new (
|
|
76
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
77
|
+
user_id VARCHAR(255) NOT NULL,
|
|
78
|
+
title TEXT NOT NULL,
|
|
79
|
+
url TEXT NOT NULL,
|
|
80
|
+
slug VARCHAR(255),
|
|
81
|
+
forwarding_enabled BOOLEAN DEFAULT FALSE,
|
|
82
|
+
pinned BOOLEAN DEFAULT FALSE,
|
|
83
|
+
access_count INTEGER DEFAULT 0,
|
|
84
|
+
last_accessed_at TIMESTAMP,
|
|
85
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
86
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
87
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
88
|
+
UNIQUE(slug)
|
|
89
|
+
)
|
|
90
|
+
`, []);
|
|
91
|
+
// Copy data
|
|
92
|
+
await execute(`
|
|
93
|
+
INSERT INTO bookmarks_new
|
|
94
|
+
SELECT * FROM bookmarks
|
|
95
|
+
`, []);
|
|
96
|
+
// Drop old table
|
|
97
|
+
await execute('DROP TABLE bookmarks', []);
|
|
98
|
+
// Rename new table
|
|
99
|
+
await execute('ALTER TABLE bookmarks_new RENAME TO bookmarks', []);
|
|
100
|
+
// Recreate indexes
|
|
101
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_user_id ON bookmarks(user_id)', []);
|
|
102
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_slug ON bookmarks(slug)', []);
|
|
103
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_pinned ON bookmarks(pinned)', []);
|
|
104
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_access_count ON bookmarks(access_count)', []);
|
|
105
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_last_accessed ON bookmarks(last_accessed_at)', []);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export async function down() {
|
|
109
|
+
const DB_TYPE = process.env.DB_TYPE || 'sqlite';
|
|
110
|
+
if (DB_TYPE === 'postgresql') {
|
|
111
|
+
// Drop the global unique index
|
|
112
|
+
await execute('DROP INDEX IF EXISTS idx_bookmarks_slug_unique', []);
|
|
113
|
+
// Restore the per-user unique constraint
|
|
114
|
+
await execute('ALTER TABLE bookmarks ADD CONSTRAINT bookmarks_user_id_slug_key UNIQUE (user_id, slug)', []);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// SQLite: Recreate table with per-user unique constraint
|
|
118
|
+
await execute(`
|
|
119
|
+
CREATE TABLE bookmarks_old (
|
|
120
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
121
|
+
user_id VARCHAR(255) NOT NULL,
|
|
122
|
+
title TEXT NOT NULL,
|
|
123
|
+
url TEXT NOT NULL,
|
|
124
|
+
slug VARCHAR(255),
|
|
125
|
+
forwarding_enabled BOOLEAN DEFAULT FALSE,
|
|
126
|
+
pinned BOOLEAN DEFAULT FALSE,
|
|
127
|
+
access_count INTEGER DEFAULT 0,
|
|
128
|
+
last_accessed_at TIMESTAMP,
|
|
129
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
130
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
131
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
132
|
+
UNIQUE(user_id, slug)
|
|
133
|
+
)
|
|
134
|
+
`, []);
|
|
135
|
+
// Copy data
|
|
136
|
+
await execute(`
|
|
137
|
+
INSERT INTO bookmarks_old
|
|
138
|
+
SELECT * FROM bookmarks
|
|
139
|
+
`, []);
|
|
140
|
+
// Drop current table
|
|
141
|
+
await execute('DROP TABLE bookmarks', []);
|
|
142
|
+
// Rename old table
|
|
143
|
+
await execute('ALTER TABLE bookmarks_old RENAME TO bookmarks', []);
|
|
144
|
+
// Recreate indexes
|
|
145
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_user_id ON bookmarks(user_id)', []);
|
|
146
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_slug ON bookmarks(slug)', []);
|
|
147
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_pinned ON bookmarks(pinned)', []);
|
|
148
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_access_count ON bookmarks(access_count)', []);
|
|
149
|
+
await execute('CREATE INDEX IF NOT EXISTS idx_bookmarks_last_accessed ON bookmarks(last_accessed_at)', []);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=004_make_slug_globally_unique.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"004_make_slug_globally_unique.js","sourceRoot":"","sources":["../../../src/db/migrations/004_make_slug_globally_unique.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"005_add_email_verification.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/005_add_email_verification.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,QAAQ,CAAC;AACjC,eAAO,MAAM,aAAa,kCAAkC,CAAC;AAE7D,wBAAsB,EAAE,kBAuFvB;AAED,wBAAsB,IAAI,kBAiBzB"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { execute, query } from '../index.js';
|
|
2
|
+
export const migrationId = '005';
|
|
3
|
+
export const migrationName = 'Add email verification system';
|
|
4
|
+
export async function up() {
|
|
5
|
+
const DB_TYPE = process.env.DB_TYPE || 'sqlite';
|
|
6
|
+
if (DB_TYPE === 'postgresql') {
|
|
7
|
+
// Add email_pending column to users table
|
|
8
|
+
await execute(`
|
|
9
|
+
ALTER TABLE users
|
|
10
|
+
ADD COLUMN IF NOT EXISTS email_pending VARCHAR(255)
|
|
11
|
+
`, []);
|
|
12
|
+
// Create email verification tokens table
|
|
13
|
+
await execute(`
|
|
14
|
+
CREATE TABLE IF NOT EXISTS email_verification_tokens (
|
|
15
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
16
|
+
user_id VARCHAR(255) NOT NULL,
|
|
17
|
+
token VARCHAR(255) UNIQUE NOT NULL,
|
|
18
|
+
new_email VARCHAR(255) NOT NULL,
|
|
19
|
+
expires_at TIMESTAMP NOT NULL,
|
|
20
|
+
used BOOLEAN DEFAULT FALSE,
|
|
21
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
22
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
23
|
+
)
|
|
24
|
+
`, []);
|
|
25
|
+
// Create indexes
|
|
26
|
+
await execute(`
|
|
27
|
+
CREATE INDEX IF NOT EXISTS idx_email_verification_tokens_token
|
|
28
|
+
ON email_verification_tokens(token)
|
|
29
|
+
`, []);
|
|
30
|
+
await execute(`
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_email_verification_tokens_user
|
|
32
|
+
ON email_verification_tokens(user_id)
|
|
33
|
+
`, []);
|
|
34
|
+
await execute(`
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_email_verification_tokens_expires
|
|
36
|
+
ON email_verification_tokens(expires_at)
|
|
37
|
+
`, []);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// SQLite: Check if column exists before adding
|
|
41
|
+
const tableInfo = await query("PRAGMA table_info(users)", []);
|
|
42
|
+
const hasEmailPending = tableInfo.some((col) => col.name === 'email_pending');
|
|
43
|
+
if (!hasEmailPending) {
|
|
44
|
+
// SQLite doesn't support ALTER TABLE ADD COLUMN IF NOT EXISTS, so we need to recreate
|
|
45
|
+
// But we'll use a safer approach: just add the column (it will fail if exists, but that's ok)
|
|
46
|
+
try {
|
|
47
|
+
await execute(`ALTER TABLE users ADD COLUMN email_pending VARCHAR(255)`, []);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
// Column might already exist, ignore
|
|
51
|
+
if (!error.message?.includes('duplicate column name')) {
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Create email verification tokens table
|
|
57
|
+
await execute(`
|
|
58
|
+
CREATE TABLE IF NOT EXISTS email_verification_tokens (
|
|
59
|
+
id TEXT PRIMARY KEY,
|
|
60
|
+
user_id TEXT NOT NULL,
|
|
61
|
+
token TEXT UNIQUE NOT NULL,
|
|
62
|
+
new_email TEXT NOT NULL,
|
|
63
|
+
expires_at TEXT NOT NULL,
|
|
64
|
+
used INTEGER DEFAULT 0,
|
|
65
|
+
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
66
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
67
|
+
)
|
|
68
|
+
`, []);
|
|
69
|
+
// Create indexes
|
|
70
|
+
await execute(`
|
|
71
|
+
CREATE INDEX IF NOT EXISTS idx_email_verification_tokens_token
|
|
72
|
+
ON email_verification_tokens(token)
|
|
73
|
+
`, []);
|
|
74
|
+
await execute(`
|
|
75
|
+
CREATE INDEX IF NOT EXISTS idx_email_verification_tokens_user
|
|
76
|
+
ON email_verification_tokens(user_id)
|
|
77
|
+
`, []);
|
|
78
|
+
await execute(`
|
|
79
|
+
CREATE INDEX IF NOT EXISTS idx_email_verification_tokens_expires
|
|
80
|
+
ON email_verification_tokens(expires_at)
|
|
81
|
+
`, []);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export async function down() {
|
|
85
|
+
const DB_TYPE = process.env.DB_TYPE || 'sqlite';
|
|
86
|
+
if (DB_TYPE === 'postgresql') {
|
|
87
|
+
await execute(`DROP INDEX IF EXISTS idx_email_verification_tokens_expires`, []);
|
|
88
|
+
await execute(`DROP INDEX IF EXISTS idx_email_verification_tokens_user`, []);
|
|
89
|
+
await execute(`DROP INDEX IF EXISTS idx_email_verification_tokens_token`, []);
|
|
90
|
+
await execute(`DROP TABLE IF EXISTS email_verification_tokens`, []);
|
|
91
|
+
await execute(`ALTER TABLE users DROP COLUMN IF EXISTS email_pending`, []);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
await execute(`DROP INDEX IF EXISTS idx_email_verification_tokens_expires`, []);
|
|
95
|
+
await execute(`DROP INDEX IF EXISTS idx_email_verification_tokens_user`, []);
|
|
96
|
+
await execute(`DROP INDEX IF EXISTS idx_email_verification_tokens_token`, []);
|
|
97
|
+
await execute(`DROP TABLE IF EXISTS email_verification_tokens`, []);
|
|
98
|
+
// SQLite doesn't support DROP COLUMN easily, so we'll leave email_pending
|
|
99
|
+
// It won't cause issues if it exists
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=005_add_email_verification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"005_add_email_verification.js","sourceRoot":"","sources":["../../../src/db/migrations/005_add_email_verification.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC;AACjC,MAAM,CAAC,MAAM,aAAa,GAAG,+BAA+B,CAAC;AAE7D,MAAM,CAAC,KAAK,UAAU,EAAE;IACtB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,QAAQ,CAAC;IAEhD,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;QAC7B,0CAA0C;QAC1C,MAAM,OAAO,CAAC;;;KAGb,EAAE,EAAE,CAAC,CAAC;QAEP,yCAAyC;QACzC,MAAM,OAAO,CAAC;;;;;;;;;;;KAWb,EAAE,EAAE,CAAC,CAAC;QAEP,iBAAiB;QACjB,MAAM,OAAO,CAAC;;;KAGb,EAAE,EAAE,CAAC,CAAC;QAEP,MAAM,OAAO,CAAC;;;KAGb,EAAE,EAAE,CAAC,CAAC;QAEP,MAAM,OAAO,CAAC;;;KAGb,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;SAAM,CAAC;QACN,+CAA+C;QAC/C,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,0BAA0B,EAAE,EAAE,CAAC,CAAC;QAC9D,MAAM,eAAe,GAAI,SAAmB,CAAC,IAAI,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC;QAE9F,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,sFAAsF;YACtF,8FAA8F;YAC9F,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,yDAAyD,EAAE,EAAE,CAAC,CAAC;YAC/E,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,qCAAqC;gBACrC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;oBACtD,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;QAED,yCAAyC;QACzC,MAAM,OAAO,CAAC;;;;;;;;;;;KAWb,EAAE,EAAE,CAAC,CAAC;QAEP,iBAAiB;QACjB,MAAM,OAAO,CAAC;;;KAGb,EAAE,EAAE,CAAC,CAAC;QAEP,MAAM,OAAO,CAAC;;;KAGb,EAAE,EAAE,CAAC,CAAC;QAEP,MAAM,OAAO,CAAC;;;KAGb,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,QAAQ,CAAC;IAEhD,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;QAC7B,MAAM,OAAO,CAAC,4DAA4D,EAAE,EAAE,CAAC,CAAC;QAChF,MAAM,OAAO,CAAC,yDAAyD,EAAE,EAAE,CAAC,CAAC;QAC7E,MAAM,OAAO,CAAC,0DAA0D,EAAE,EAAE,CAAC,CAAC;QAC9E,MAAM,OAAO,CAAC,gDAAgD,EAAE,EAAE,CAAC,CAAC;QACpE,MAAM,OAAO,CAAC,uDAAuD,EAAE,EAAE,CAAC,CAAC;IAC7E,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,CAAC,4DAA4D,EAAE,EAAE,CAAC,CAAC;QAChF,MAAM,OAAO,CAAC,yDAAyD,EAAE,EAAE,CAAC,CAAC;QAC7E,MAAM,OAAO,CAAC,0DAA0D,EAAE,EAAE,CAAC,CAAC;QAC9E,MAAM,OAAO,CAAC,gDAAgD,EAAE,EAAE,CAAC,CAAC;QACpE,0EAA0E;QAC1E,qCAAqC;IACvC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration: Add refresh_tokens table for CLOUD mode auth (short-lived access JWT + refresh cookie).
|
|
3
|
+
* Used only in CLOUD mode; table is harmless when empty in SELFHOSTED.
|
|
4
|
+
*/
|
|
5
|
+
export declare const migrationId = "006_refresh_tokens";
|
|
6
|
+
export declare const migrationName = "Add refresh_tokens table for CLOUD mode";
|
|
7
|
+
export declare function up(): Promise<void>;
|
|
8
|
+
export declare function down(): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=006_refresh_tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"006_refresh_tokens.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/006_refresh_tokens.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,eAAO,MAAM,WAAW,uBAAuB,CAAC;AAChD,eAAO,MAAM,aAAa,4CAA4C,CAAC;AAEvE,wBAAsB,EAAE,kBA8CvB;AAED,wBAAsB,IAAI,kBAKzB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration: Add refresh_tokens table for CLOUD mode auth (short-lived access JWT + refresh cookie).
|
|
3
|
+
* Used only in CLOUD mode; table is harmless when empty in SELFHOSTED.
|
|
4
|
+
*/
|
|
5
|
+
import { execute } from '../index.js';
|
|
6
|
+
export const migrationId = '006_refresh_tokens';
|
|
7
|
+
export const migrationName = 'Add refresh_tokens table for CLOUD mode';
|
|
8
|
+
export async function up() {
|
|
9
|
+
const DB_TYPE = process.env.DB_TYPE || 'sqlite';
|
|
10
|
+
if (DB_TYPE === 'postgresql') {
|
|
11
|
+
await execute(`
|
|
12
|
+
CREATE TABLE IF NOT EXISTS refresh_tokens (
|
|
13
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
14
|
+
user_id VARCHAR(255) NOT NULL,
|
|
15
|
+
token_hash VARCHAR(255) NOT NULL,
|
|
16
|
+
expires_at TIMESTAMP NOT NULL,
|
|
17
|
+
revoked BOOLEAN DEFAULT FALSE,
|
|
18
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
19
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
20
|
+
)
|
|
21
|
+
`, []);
|
|
22
|
+
await execute(`
|
|
23
|
+
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_token_hash ON refresh_tokens(token_hash)
|
|
24
|
+
`, []);
|
|
25
|
+
await execute(`
|
|
26
|
+
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user_id ON refresh_tokens(user_id)
|
|
27
|
+
`, []);
|
|
28
|
+
await execute(`
|
|
29
|
+
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_expires_at ON refresh_tokens(expires_at)
|
|
30
|
+
`, []);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
await execute(`
|
|
34
|
+
CREATE TABLE IF NOT EXISTS refresh_tokens (
|
|
35
|
+
id TEXT PRIMARY KEY,
|
|
36
|
+
user_id TEXT NOT NULL,
|
|
37
|
+
token_hash TEXT NOT NULL,
|
|
38
|
+
expires_at TEXT NOT NULL,
|
|
39
|
+
revoked INTEGER DEFAULT 0,
|
|
40
|
+
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
41
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
42
|
+
)
|
|
43
|
+
`, []);
|
|
44
|
+
await execute(`
|
|
45
|
+
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_token_hash ON refresh_tokens(token_hash)
|
|
46
|
+
`, []);
|
|
47
|
+
await execute(`
|
|
48
|
+
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user_id ON refresh_tokens(user_id)
|
|
49
|
+
`, []);
|
|
50
|
+
await execute(`
|
|
51
|
+
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_expires_at ON refresh_tokens(expires_at)
|
|
52
|
+
`, []);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export async function down() {
|
|
56
|
+
await execute(`DROP INDEX IF EXISTS idx_refresh_tokens_expires_at`, []);
|
|
57
|
+
await execute(`DROP INDEX IF EXISTS idx_refresh_tokens_user_id`, []);
|
|
58
|
+
await execute(`DROP INDEX IF EXISTS idx_refresh_tokens_token_hash`, []);
|
|
59
|
+
await execute(`DROP TABLE IF EXISTS refresh_tokens`, []);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=006_refresh_tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"006_refresh_tokens.js","sourceRoot":"","sources":["../../../src/db/migrations/006_refresh_tokens.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,MAAM,CAAC,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAChD,MAAM,CAAC,MAAM,aAAa,GAAG,yCAAyC,CAAC;AAEvE,MAAM,CAAC,KAAK,UAAU,EAAE;IACtB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,QAAQ,CAAC;IAEhD,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;QAC7B,MAAM,OAAO,CAAC;;;;;;;;;;KAUb,EAAE,EAAE,CAAC,CAAC;QACP,MAAM,OAAO,CAAC;;KAEb,EAAE,EAAE,CAAC,CAAC;QACP,MAAM,OAAO,CAAC;;KAEb,EAAE,EAAE,CAAC,CAAC;QACP,MAAM,OAAO,CAAC;;KAEb,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,CAAC;;;;;;;;;;KAUb,EAAE,EAAE,CAAC,CAAC;QACP,MAAM,OAAO,CAAC;;KAEb,EAAE,EAAE,CAAC,CAAC;QACP,MAAM,OAAO,CAAC;;KAEb,EAAE,EAAE,CAAC,CAAC;QACP,MAAM,OAAO,CAAC;;KAEb,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,OAAO,CAAC,oDAAoD,EAAE,EAAE,CAAC,CAAC;IACxE,MAAM,OAAO,CAAC,iDAAiD,EAAE,EAAE,CAAC,CAAC;IACrE,MAAM,OAAO,CAAC,oDAAoD,EAAE,EAAE,CAAC,CAAC;IACxE,MAAM,OAAO,CAAC,qCAAqC,EAAE,EAAE,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration: Add token_hash to password_reset_tokens; store only hash, not plaintext token.
|
|
3
|
+
* New rows use token_hash for lookup; token column holds placeholder 'h:'+id. Legacy rows
|
|
4
|
+
* (token_hash IS NULL) are looked up by token and migrated on use.
|
|
5
|
+
*/
|
|
6
|
+
export declare const migrationId = "007_password_reset_token_hash";
|
|
7
|
+
export declare const migrationName = "Add password_reset_tokens.token_hash for secure storage";
|
|
8
|
+
export declare function up(): Promise<void>;
|
|
9
|
+
export declare function down(): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=007_password_reset_token_hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"007_password_reset_token_hash.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/007_password_reset_token_hash.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,eAAO,MAAM,WAAW,kCAAkC,CAAC;AAC3D,eAAO,MAAM,aAAa,4DAA4D,CAAC;AAEvF,wBAAsB,EAAE,kBAsBvB;AAED,wBAAsB,IAAI,kBAOzB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration: Add token_hash to password_reset_tokens; store only hash, not plaintext token.
|
|
3
|
+
* New rows use token_hash for lookup; token column holds placeholder 'h:'+id. Legacy rows
|
|
4
|
+
* (token_hash IS NULL) are looked up by token and migrated on use.
|
|
5
|
+
*/
|
|
6
|
+
import { execute } from '../index.js';
|
|
7
|
+
export const migrationId = '007_password_reset_token_hash';
|
|
8
|
+
export const migrationName = 'Add password_reset_tokens.token_hash for secure storage';
|
|
9
|
+
export async function up() {
|
|
10
|
+
const DB_TYPE = process.env.DB_TYPE || 'sqlite';
|
|
11
|
+
if (DB_TYPE === 'postgresql') {
|
|
12
|
+
await execute(`
|
|
13
|
+
ALTER TABLE password_reset_tokens
|
|
14
|
+
ADD COLUMN IF NOT EXISTS token_hash VARCHAR(255)
|
|
15
|
+
`, []);
|
|
16
|
+
await execute(`
|
|
17
|
+
CREATE INDEX IF NOT EXISTS idx_password_reset_tokens_token_hash
|
|
18
|
+
ON password_reset_tokens(token_hash)
|
|
19
|
+
`, []);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
// SQLite: ADD COLUMN only
|
|
23
|
+
await execute(`
|
|
24
|
+
ALTER TABLE password_reset_tokens ADD COLUMN token_hash TEXT
|
|
25
|
+
`, []);
|
|
26
|
+
await execute(`
|
|
27
|
+
CREATE INDEX IF NOT EXISTS idx_password_reset_tokens_token_hash
|
|
28
|
+
ON password_reset_tokens(token_hash)
|
|
29
|
+
`, []);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function down() {
|
|
33
|
+
await execute(`DROP INDEX IF EXISTS idx_password_reset_tokens_token_hash`, []);
|
|
34
|
+
// SQLite does not support DROP COLUMN easily; leave column for safety
|
|
35
|
+
const DB_TYPE = process.env.DB_TYPE || 'sqlite';
|
|
36
|
+
if (DB_TYPE === 'postgresql') {
|
|
37
|
+
await execute(`ALTER TABLE password_reset_tokens DROP COLUMN IF EXISTS token_hash`, []);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=007_password_reset_token_hash.js.map
|