diff --git a/client/containers/SuperAdminDashboard/CustomDomains/CustomDomains.tsx b/client/containers/SuperAdminDashboard/CustomDomains/CustomDomains.tsx new file mode 100644 index 000000000..d64bc50b1 --- /dev/null +++ b/client/containers/SuperAdminDashboard/CustomDomains/CustomDomains.tsx @@ -0,0 +1,268 @@ +import React, { useCallback, useMemo, useState } from 'react'; + +import { + Button, + Callout, + Classes, + Dialog, + FormGroup, + InputGroup, + Intent, + NonIdealState, +} from '@blueprintjs/core'; + +import { apiFetch } from 'client/utils/apiFetch'; + +import './customDomains.scss'; + +const CNAME_TARGET = 'custom-domain-1.pubpub.org'; + +type CommunityDomain = { + id: string; + subdomain: string; + domain: string; + title: string; +}; + +type Props = { + communities: CommunityDomain[]; + cloudflareConfigured: boolean; +}; + +const CustomDomains = (props: Props) => { + const [communities, setCommunities] = useState(props.communities); + const [communityIdentifier, setCommunityIdentifier] = useState(''); + const [newDomain, setNewDomain] = useState(''); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + const [success, setSuccess] = useState(null); + const [copied, setCopied] = useState(false); + const [pendingRemove, setPendingRemove] = useState(null); + const [filterText, setFilterText] = useState(''); + + const filteredCommunities = useMemo(() => { + const q = filterText.toLowerCase().trim(); + if (!q) return communities; + return communities.filter( + (c) => + c.domain.toLowerCase().includes(q) || + c.title.toLowerCase().includes(q) || + c.subdomain.toLowerCase().includes(q), + ); + }, [communities, filterText]); + + const cnameMessage = `Please point your domain's CNAME record to:\n\n${CNAME_TARGET}\n\nThis should be set up with your DNS provider. The CNAME record for your custom domain should point to ${CNAME_TARGET}. Once the DNS change propagates (usually within a few minutes to a few hours), your custom domain will be active.`; + + const handleCopyCname = useCallback(() => { + navigator.clipboard.writeText(cnameMessage); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }, [cnameMessage]); + + const handleAdd = useCallback(async () => { + if (!communityIdentifier.trim() || !newDomain.trim()) { + setError('Both community ID/subdomain and domain are required.'); + return; + } + setIsLoading(true); + setError(null); + setSuccess(null); + try { + const result = await apiFetch.post('/api/superadmin/custom-domains', { + communityId: communityIdentifier.trim(), + domain: newDomain.trim(), + }); + setCommunities((prev) => { + const filtered = prev.filter((c) => c.id !== result.id); + return [...filtered, result].sort((a, b) => a.domain.localeCompare(b.domain)); + }); + setCommunityIdentifier(''); + setNewDomain(''); + setSuccess(`Custom domain "${result.domain}" added for "${result.title}".`); + } catch (err: any) { + setError(err?.message || 'Failed to add custom domain.'); + } finally { + setIsLoading(false); + } + }, [communityIdentifier, newDomain]); + + const handleRemove = useCallback(async (community: CommunityDomain) => { + setPendingRemove(null); + setIsLoading(true); + setError(null); + setSuccess(null); + try { + await apiFetch.delete('/api/superadmin/custom-domains', { communityId: community.id }); + setCommunities((prev) => prev.filter((c) => c.id !== community.id)); + setSuccess(`Custom domain "${community.domain}" removed from "${community.title}".`); + } catch (err: any) { + setError(err?.message || 'Failed to remove custom domain.'); + } finally { + setIsLoading(false); + } + }, []); + + return ( +
+

Custom Domains

+ + {!props.cloudflareConfigured && ( + + Cloudflare custom hostname API is not configured. Set{' '} + CLOUDFLARE_CUSTOM_HOSTNAME_API_TOKEN and{' '} + CLOUDFLARE_ZONE_TAG environment variables. Domains can still be + viewed but add/remove will fail. + + )} + +

User Instructions

+ + + {error && ( + + {error} + + )} + {success && ( + + {success} + + )} + +

Add Domain

+
+ + setCommunityIdentifier(e.target.value)} + disabled={isLoading} + /> + + + setNewDomain(e.target.value)} + disabled={isLoading} + /> + +
+ +

Manage Domains

+ {communities.length === 0 ? ( + + ) : ( + <> +
+ setFilterText(e.target.value)} + /> + + {filterText && filteredCommunities.length !== communities.length + ? `Showing ${filteredCommunities.length} of ${communities.length}` + : `Total: ${communities.length}`}{' '} + custom domain{communities.length !== 1 ? 's' : ''} + +
+ + + + + + + + + + {filteredCommunities.map((c) => ( + + + + + + + ))} + +
DomainCommunitySubdomain +
+ + {c.domain} + + {c.title} + {c.subdomain} + +
+ + )} + + setPendingRemove(null)} + title="Remove Custom Domain" + icon="warning-sign" + > +
+

+ Remove custom domain {pendingRemove?.domain} from{' '} + {pendingRemove?.title}? +

+

This will also remove it from Cloudflare.

+
+
+
+ + +
+
+
+
+ ); +}; + +export default CustomDomains; diff --git a/client/containers/SuperAdminDashboard/CustomDomains/customDomains.scss b/client/containers/SuperAdminDashboard/CustomDomains/customDomains.scss new file mode 100644 index 000000000..3c69f9afb --- /dev/null +++ b/client/containers/SuperAdminDashboard/CustomDomains/customDomains.scss @@ -0,0 +1,115 @@ +.custom-domains-component { + .cname-notice { + display: block; + width: 100%; + margin-bottom: 20px; + padding: 12px 16px; + background: #f5f5f5; + border: none; + border-radius: 4px; + cursor: pointer; + text-align: left; + font: inherit; + color: inherit; + + &:hover { + background: #ebebeb; + } + + p { + margin: 0 0 8px; + + &:last-of-type { + margin-bottom: 4px; + } + } + + code { + font-weight: 600; + } + + .copy-hint { + font-size: 12px; + color: #888; + } + } + + .add-domain-form { + display: flex; + gap: 10px; + margin-bottom: 20px; + align-items: flex-end; + + .bp3-form-group { + margin-bottom: 0; + } + } + + .filter-bar { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 10px; + + .bp3-input-group { + flex: 0 0 400px; + } + } + + .domain-count { + font-size: 13px; + color: #888; + white-space: nowrap; + } + + .domains-table { + width: 100%; + border-collapse: collapse; + table-layout: fixed; + + th, + td { + padding: 8px 12px; + text-align: left; + border-bottom: 1px solid #e1e1e1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + th:nth-child(1), + td:nth-child(1) { + width: 35%; + } + + th:nth-child(2), + td:nth-child(2) { + width: calc(45% - 50px); + } + + th:nth-child(3), + td:nth-child(3) { + width: 20%; + } + + th:nth-child(4), + td:nth-child(4) { + width: 50px; + text-align: right; + } + + th { + font-weight: 600; + background: #f5f5f5; + } + + .community-link { + color: #137cbd; + text-decoration: none; + + &:hover { + text-decoration: underline; + } + } + } +} diff --git a/client/containers/SuperAdminDashboard/CustomDomains/index.ts b/client/containers/SuperAdminDashboard/CustomDomains/index.ts new file mode 100644 index 000000000..f97676d53 --- /dev/null +++ b/client/containers/SuperAdminDashboard/CustomDomains/index.ts @@ -0,0 +1 @@ +export { default } from './CustomDomains'; diff --git a/client/containers/SuperAdminDashboard/tabs.tsx b/client/containers/SuperAdminDashboard/tabs.tsx index c0d376aba..16dc124d0 100644 --- a/client/containers/SuperAdminDashboard/tabs.tsx +++ b/client/containers/SuperAdminDashboard/tabs.tsx @@ -3,6 +3,7 @@ import type { SuperAdminTabKind } from 'utils/superAdmin'; import React from 'react'; import CommunitySpam from './CommunitySpam'; +import CustomDomains from './CustomDomains'; import ExploreCommunities from './ExploreCommunities'; import LandingPageFeatures from './LandingPageFeatures'; import PlatformAnalytics from './PlatformAnalytics'; @@ -18,6 +19,10 @@ export const superAdminTabs: Record = { title: 'Analytics', component: PlatformAnalytics, }, + customDomains: { + title: 'Custom Domains', + component: CustomDomains, + }, exploreCommunities: { title: 'Explore Page', component: ExploreCommunities, diff --git a/infra/.env.dev.enc b/infra/.env.dev.enc index 670655922..e364a6caa 100644 --- a/infra/.env.dev.enc +++ b/infra/.env.dev.enc @@ -1,51 +1,52 @@ -AES_ENCRYPTION_KEY=ENC[AES256_GCM,data:axJ9+UEhNdCZ2IxC3fE1LhBmg7gXckElHg+mwDqoRlaTS4u87Hqq81Jfl1c4ENMvd0nD8saxibCULxljzcVGsA==,iv:jQDpB81KvSJZLfBDuWJRGkIfi4HPXqu4+40u0QamBVY=,tag:R2uB15iE1NFY8EPufzEzEQ==,type:str] -ALTCHA_HMAC_KEY=ENC[AES256_GCM,data:tr+T885SZ1254fOmEb7eX4g4dSvTa2JVH7nHgBZn/9tBHWtrpZ7oSNyLjWlbJ0a4kd9Egv1Zo2P03hl9EPLz5w==,iv:poGas++m3+eEG6KQQfmW6k3hNukA46pj8bJg+H3Ki8w=,tag:wOGSQKGiClXBjlnhmuwpGg==,type:str] -AWS_ACCESS_KEY_ID=ENC[AES256_GCM,data:CMf3DsTQV/r4EyldktoCIJ522Fs=,iv:/g5n/E7vL69sNg8bNH6srGSVcVqTWS8fpspasRwa5X0=,tag:SORQgs9jOiw8QaoLCEhB2w==,type:str] -AWS_BACKUP_ACCESS_KEY_ID=ENC[AES256_GCM,data:ASU5ZXKGFU+87Pb44Y511+Ve6+8=,iv:kejdRbTiXeEGBD5mauKzr3jd6xpylnJkod/2Q2EaMaA=,tag:uPr5Gsq2phkkKDCWWIkUGA==,type:str] -AWS_BACKUP_SECRET_ACCESS_KEY=ENC[AES256_GCM,data:BfnR3K5LTHdxJDZPEXTecanphxg9xbNhLS5y54cc5VtvLef6XMiBhg==,iv:owAFuMDYFsv+9yebhPwQLDrvHmc5i5iarKK/Clx13zs=,tag:Ly5OrfqhEunJRwqRljzkWQ==,type:str] -AWS_SECRET_ACCESS_KEY=ENC[AES256_GCM,data:OWan8dbt58r0eCiGbCqg/IQpk8oT2SXtDAN2rMov4WLFBoGTQ0l9vg==,iv:S3bSI4eCCnPSY04TvAS+gRDbpr901p/YLGkxgv0g3Go=,tag:++kPwDKbmpuVxHct27xqKQ==,type:str] -BACKUPS_SECRET=ENC[AES256_GCM,data:oECFXHDgGZMGzZE1xjCjFZAJbP/hjoh3j8m6GG/X8TabCdg+RT6a5iWRM8c=,iv:vM7QtMQCks4N/0UMkAVlb97R8/YFyN6ldFhdkxiMaxY=,tag:vNMG9HPaUMCE7azeN9g0Fw==,type:str] -CLOUDFLARE_ANALYTICS_API_TOKEN=ENC[AES256_GCM,data:99dkoLf7lXnEZ0YHJa+tTfD/HGiTflFZLtZrOyfzpHIkF/DszeCd3wPujEo6MPe45dZkKzE=,iv:0XABiWipgpd2BSfAezAhGtfPU2ErTsgASOIfVZeDoKc=,tag:/jpn1Vdp9YOhVXt/Gc3Hqg==,type:str] -CLOUDFLARE_ZONE_TAG=ENC[AES256_GCM,data:SbB6uzQShvFJcDKXrGy3ouBsjhPS8+IEV7JDcu3hO4Y=,iv:4xb8vbw9o+yGHJpEqKh/EnfnGskrb8ZyBQWw/NQufgs=,tag:74BoUnWROQNpe44Ztuke3A==,type:str] -DATABASE_URL=ENC[AES256_GCM,data:zf0Bp3fwYD/QRqnFlQtXNEE4ejdFLWWb+FyJqfXj77ifR3nMOmPR1hylKck=,iv:Gymc4g5Uw7ZnYdaaE4hARVyDwEiUhXwrs7p6v18L40M=,tag:OuwVP19O1BiQrfy6XRjaKQ==,type:str] -DATACITE_DEPOSIT_URL=ENC[AES256_GCM,data:v2DVBZhnKZhYFMB8iBcsPAVuMv8Oi1DEo3TR2ZdJ3ck24A==,iv:Wb1QHjOkxoP8CJccp2EELcbwlX6X2eQVQsD7MJP/I10=,tag:g3/T/m7fzGc1+E+kCdiLyg==,type:str] -DOI_LOGIN_ID=ENC[AES256_GCM,data:iMYGX2j+,iv:MDluK695ltVfkxuxwJ7cS5gRme4FTl4tP38/doWREGc=,tag:ZwrRJ+5MO8Gg0Ti987veqA==,type:str] -DOI_LOGIN_PASSWORD=ENC[AES256_GCM,data:HEJ4LgCAVKd43avW1Uhw7vvaeDU=,iv:4ig7Au+AGuHchT+vngKETerjafy6kLSFNfsepjRSmao=,tag:Z0U5DKylV8XWv0oh+f9vCA==,type:str] -DOI_SUBMISSION_URL=ENC[AES256_GCM,data:q0j0NZg32KQ+FvWre6/Jz3Ml7JuYgaasY0t5PvBonP3ReH4LEzcTicA=,iv:sZmkEFzqJGdP0zNR1HwD0BNzLcMBONA6Cxhf5ZjVFZY=,tag:FCzHZI7Cbt2Ths10PJxmUA==,type:str] -FASTLY_PURGE_TOKEN=ENC[AES256_GCM,data:sH1Mf+EgwGsTXyx5hczuoYCDogSN3Ow2SSe0qxV+qvk=,iv:GTIDJgYdSdV8gScI80c/PrgqNMXtrtDuHWE69POHdfU=,tag:R8qMSUar5VZh6pgisAZNxQ==,type:str] -FASTLY_SERVICE_ID=ENC[AES256_GCM,data:1VXXr4NqCeE4vRosWiB5L3FcMDwRnA==,iv:+QI8iwScws2wDaz9vug+rZOdk1Ix7+OkZL6yRb+yJqY=,tag:6QuCd/QdbsTDzzJfDCOi3w==,type:str] -FIREBASE_SERVICE_ACCOUNT_BASE64=ENC[AES256_GCM,data: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,iv:i21WfFl9xLBv1NQGfOPPHw0XeozJLNvzOzDChydI1+c=,tag:DmrdU99Kq4CI5RG1gW7AvA==,type:str] -IS_DUQDUQ=ENC[AES256_GCM,data:m/Wlbg==,iv:kxZ6BQKi9LQC98jlBMnK6HBi+Tsd1R/0QQiTlV8zXy8=,tag:9ZcIspVnNP+0X343u/poAg==,type:str] -JWT_SIGNING_SECRET=ENC[AES256_GCM,data:1R3UNL8m0Wsupk8ikzIrdkcakhJAL2fxgDBy6qDDz0CkWGbGfldjaZHeAQdrTTaCpPTfdyQ0QpXkSbdhoxzeG8+WTUoGTvy+2vyaysp8Lsm5PelXooPvWuXFav2IA02BI32dwFXnP0INSgSDwOqCC5Op648kfgQy3wbw5PkZ0+4hsrtjGJpSaCFiix0ZJtqbADrMVo8UcHVubALvf0JvpsCa6fN1TQ6CTSZZwG0mZm4WM7ohDYNPGjkpSdlGiYLMKL20bN+DkT+ktMt4XHQP8XBDoxkIm5CabQLTnStswD+e/SZi/RtSMYoqZHmWRlBJD3T9Blo3rYNKAjYoBkL1/PfeVZQKZ/zwag7suh5ga2Uc4aNYx4Ywdrq5uCbcn4fw5yVXi+ahiPsWHdTOy5IA0a1Eu6PZtt3xb0sH0sMu3r6IJPNQ8tt1MUxHBktw8ScObbssToxq6Dz0dwHmZFMoUaIEb2VrnasGgloTZoX/g5HHUeA9uOfrpZB80PYu1WoauDrkrMcKVQKVxg0fNrSUn+lgdrFjT1iBXQSJVnlpnUSNjhUqsEKwvU0pbfYk2bRNXHP/aIp9Z5qqUcAtSTVi9+VrTTENPBmtRs+g4OV6UK0itsFYajDsHM6rmjYiNJ6Kz8a/4jAApwn3zuqa1+P/+rcckoEGUw/EcILBqSodMQy0Ziq5KTouJosrEpx7A7qnhU0O+1See5cWlCXk+/MlGf+6INmQabJK/IE3/VoVsXq9dWcPF1DwfLQrw8KkQuRa1SI9j6h8Gfu+tvPWBdKoMURZ2MFYc/B3cBPD74ZxL2C66kqt+hwaTZU7ki6NeUScf47l5tWjczP87mGS6ZXTkuaaQexSXAJgnnC7d5ZXM+eGlBkXNbSvbI+gZpwmKl9YoXoo38xpNWRAxkhJ9QeC4vbHeDp3mjObGLddsWxaOqQlHD7Xbjj2MlbAXkPhxdlPYgBHEJTxCrRdHRObr0NEJiwFCzj95VmMEQYdLjBUfJYZiLMLXXwY3vkDXUCr6CtrDt9j0gBHkwzIh5u1443IFh7fLKVVf36TB22UghfF1+jw0R8yh1/hHaYSU15WtrUDaJ4Jn7q6CQqIWqLl9O+kX/ScE52ChXuoITxiJaGL2kdpWvzcV+wMSw02BcXKluzkH86qZeiUslT/H/gh+5oXsNj+k+7hJNxmMmoN/x8rIWr+6LXe3wl+xNFL/7WytB9oKEx/x+58+uz42BjtEvBCIRD6uzCUalQh35dq2+Nexm3w7F+hX6AI4/Xtv8nihS+4z+v4pKsNqxZsYkfmqTHxFhZkTsj08HFbDmTkt8Cgpcarv60fEoh165kUyt++akSmMwInT6mhZXA5CbAEMPJxFw==,iv:aEvmfIc919oTGesbafArg8ScOiR9puM29YwXPA2Tx4M=,tag:YAPnsi6g3pGaQ0/xY7WQLA==,type:str] -MAILCHIMP_API_KEY=ENC[AES256_GCM,data:QRtXP/orHJLuqO6mzFyNFv9xgpXiy5abML5S0/Bs0bYwQJNe,iv:zjxC0niC7yHPt9ikogqM+P1VM4rNmvDxH/msjfwyt5c=,tag:YFSLjzuCzarTgmWqmnRzjw==,type:str] -MAILGUN_API_KEY=ENC[AES256_GCM,data:SjH17ryD0grDl6qm5YETIcD98d5Zooc8lhpdcMCJy+B6MpjE,iv:Ll4WXtwVK+Ktx7KN1Xpam4TsWJ79+3zEcHidlDTfhrM=,tag:fenSmECuN+v1mZbMVRrNbA==,type:str] -NODE_ENV=ENC[AES256_GCM,data:cKzprAXWQeNNvg==,iv:8WaxyK50ilyW5kevsxdXC5u4mGdDX/rFA8wz+Znd/5c=,tag:YG3sOPOytCPFgCkAuut6IA==,type:str] -S3_BACKUP_ACCESS_KEY=ENC[AES256_GCM,data:IL8mgIxgREtSEjSVgP2d45HZR5I=,iv:vBi6Ue3RZOiZ3sZXZWrqIVteQBhlUI7UOrNguhgM2W8=,tag:TKz53knuHEjMFvLzls+uxg==,type:str] -S3_BACKUP_BUCKET=ENC[AES256_GCM,data:w3ExvDen4XDZVgE=,iv:FBkc2KxXyraijMGo12fDEjf6rDkWhCH/nD72u1ZLdGA=,tag:OZ23AYStaN0X4llcYkMuOg==,type:str] -S3_BACKUP_ENDPOINT=ENC[AES256_GCM,data:7KJ0+tIrYfAcN2stImqIpUpQNZBmoHGkw3BCeg5/Sv32Fww=,iv:Bi57hwIHamjj+h1bdXou7gZhRkHXBa9z4WkmKTWKVAU=,tag:KaDooClZT5KFcP/tNkC0+g==,type:str] -S3_BACKUP_SECRET_KEY=ENC[AES256_GCM,data:ndRDzNnAIO/z39/PjjO/TgX1fpFMYg79wneNSYpyy775RCAXya+uPg==,iv:f2ifJVXV9PghLy3tBhxT/8xNCg17X36SxKefqgupwmE=,tag:kCIz1Zh18zUWAyYZG7r/eA==,type:str] -SENTRY_AUTH_TOKEN=ENC[AES256_GCM,data:fRr6TmMD5L/DoDIXL8SXxPXZo3PbtYUxpwfe99N6CP8amB5absqf7uJ1J6vG/1x1jsNG3ff5fbNqeyHBL5XLTOvuUwg0TfSsYHHudmfKqWTveeJhNat+hV1lEVc92nT3pfx7Ev9nKFzLdvRXqnzSN2a4smpwK1vVfyMfMQagwOduLl7ta1mWlPzLvOZkxw1ls5rk8eaL2DSMzyfs2XwQh3DxUr/OGcyEisApdVbaJNdzWS9Z0ymUbVDj8g==,iv:Y90re1vjx4UrlB+YLw84iDmH/7WY9k5XpOPb+goYHik=,tag:4aL7e9J4Rry5wescCQfKwQ==,type:str] -SENTRY_ORG=ENC[AES256_GCM,data:DI1o,iv:1oAkQjLI6Tw/tt52HlwUu5TsIilHYp2Tl3yCouvxfgU=,tag:+sw7tMjiqZLEuH9lJ9nzFA==,type:str] -SEQUELIZE_MAX_CONNECTIONS=ENC[AES256_GCM,data:ENY=,iv:hm1Gnctbg0BEVlRLZIw/gT9wC1cPh7fe2O+Fi6+9olU=,tag:G21aUDExAQxbQusvXm2R9g==,type:str] -SLACK_WEBHOOK_URL=ENC[AES256_GCM,data:WabgkMCUq9pTRei5yV43UwpSyn74ELzPbPzSz/bUD3niNVlbaCsjYLX+bk1K3C+VWPmI84jKIIafeZHKariiKUg/IgLaXGA5HJeOfHzKeA==,iv:o4voY2+B30rAuezgtXnCNsTuv2cblpqzkTbY8Rj0HRQ=,tag:YiToUfXOSY1O+IvUoiS5uw==,type:str] -SMTP_HOST=ENC[AES256_GCM,data:hXnDTo176Hb/ZOFvAjoTVjt60P1N6kDAthV3Z1X3Jy3VpQ==,iv:38IFUneLr00GVF6YIiWRFZ/DE3R9plOOJS1zb1zFnrA=,tag:ZO/+g6mwvmFZwNo4UJQPRQ==,type:str] -SMTP_PASS=ENC[AES256_GCM,data:Yb6CrgQGrtwRa564h4q+R6CisbWOISZTzZZGxu706lYsLo+s8+OwHLG1V1M=,iv:DddCtMi5tQb4ylaF63Vl/K4llNSREufB8cz6MEHIBMM=,tag:mUg9zSJulaPGYztX0TsiVA==,type:str] -SMTP_USER=ENC[AES256_GCM,data:B/CchlwDV7iCmAgg9MSnsMjRYIg=,iv:SQrrU4d7W9YE5MW43OAP/ArtRKzZeXhTRo2J8aNjxBs=,tag:qf4v44ZOkN23gdJtKQ/qFw==,type:str] -ZOTERO_CLIENT_KEY=ENC[AES256_GCM,data:9AWyxH3AdZ7S4d7z4ELFOUGZgOU=,iv:b/RXkg4jZ+0GuU9JCLFRlDhHGoMm8k6DyUa6udrl7Ow=,tag:HGQ5zTDmu98KKYT6N5NjjQ==,type:str] -ZOTERO_CLIENT_SECRET=ENC[AES256_GCM,data:7d0YA4V1flSwHGCtWu8ycMOnsFM=,iv:xV4BXpOyCUN2YjwRpJNK1AX1Qb0bqbqW+1kUjRuWPFY=,tag:zOJwVL94j6tw1pOdzJq3+A==,type:str] -sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2M05NK3FaR1RlMGpWV1F6\nQ0lKREZ5bW9vVUJZNzZSWlhOSGl4TVVNdGhZCk5TVXAvYU5scDdvN28zQm83dVNx\nUVV0QzVNUDVOaTJic1RUZmtROUpyaVkKLS0tIHFzL2p4VEhCdkhXc3pKV3huRWVI\nTjgzcEtuQ0FMMGRtdGZiZFdEWHBKemsK/0aMFiz0AYDaOAzbTC6xfM3ENu2VYu9p\nDJVKiWwN4UJRs/EMsrd2JWVPsxuYV+CyvOyYoQ/4bS2q0/d3A6PLxw==\n-----END AGE ENCRYPTED FILE-----\n +AES_ENCRYPTION_KEY=ENC[AES256_GCM,data:kiE4hD25LU6q/R429lK5rRoFIsndrjlNNgEFwnmUR90H9xxisOSxE0mJ2Pl0zPruWC4v4yBwTFaSINV8nLxyiw==,iv:vCl+U0CB5wLkMn77DhsIyyr/7Kg/lTRUx55cFwitXsw=,tag:4vS02O2ka7MPMrSaiBr3tA==,type:str] +ALTCHA_HMAC_KEY=ENC[AES256_GCM,data:3Vpi7HOJrB+I0FXQur+t25BLrgnxUbiJHmIzZ/VzfbVqkh8x9BfJ8pX8S4+KRRIvqu8jKLdQknlmeVJXN3Wlrw==,iv:ej1Z6Ofg04uGryiRkmuUPnutxSsm5YUdw7dd1CV70cg=,tag:nIn0I/9MulTNE/lF5XwtIg==,type:str] +AWS_ACCESS_KEY_ID=ENC[AES256_GCM,data:uGE6kI1FyVVOOyDQhq1me0wgAl4=,iv:4UP5BxIGsmezCKzPpGZw2OAFSyg0laCGo5VS0+JdDlI=,tag:DzNOhbV0XmbK7DTfuJKlKg==,type:str] +AWS_BACKUP_ACCESS_KEY_ID=ENC[AES256_GCM,data:83F3Ny2MG2WDMLQeEt95SAr5ZpI=,iv:0lYhmlFPyivbrrGbZQiYuXvONqPxFJ24c7O3z5KAGZQ=,tag:yUwwJrnGbjcL11m/wueEBw==,type:str] +AWS_BACKUP_SECRET_ACCESS_KEY=ENC[AES256_GCM,data:5JIPuM+LTyvXZEUa2wRkQcsc1I+HTLqKAhFVvSnGHjc3tF7feFpljg==,iv:NMiB/M1fibZJsDHWoBeP91fUiJehUQuczXjSlFS24Mw=,tag:pJ1Ajm2P+kn0l4inLUZzhQ==,type:str] +AWS_SECRET_ACCESS_KEY=ENC[AES256_GCM,data:EA1eMSF4y2p0rwZoEnSuIO12RjJSGuoMRxwEKO5W4mnbkWATAbnkKg==,iv:QiXrKSk9ac8MAkR4ZzLZYRQzBsZvHgi1tZSlgSMbZJ4=,tag:3Rsb67ZyVV/2QRbGPoxKUg==,type:str] +BACKUPS_SECRET=ENC[AES256_GCM,data:3kDU/yvCW6LCMW1oTV+PPM0lSkFOb5N37dfVQbhWL8IE6qGR9pBTd3ChQI0=,iv:Gz73ZfhHfupekGjxNeRf2yKpx0NrqV9u4IkrnJr9XZ0=,tag:ggX/c187fG7Hut2WPaTw8w==,type:str] +CLOUDFLARE_ANALYTICS_API_TOKEN=ENC[AES256_GCM,data:11ZNMtSRNImyhFVFRXMeVXxLVZkLkhepAxWkx4FRGfgWeQIh7kAKgBDC+W9oZXlLW1/57vI=,iv:EoiTt99j2p6vsj2H9SLePdT5I9jcTa3VGFweyyzG9nE=,tag:9vu0C1nqT9XdKFry0h/idA==,type:str] +CLOUDFLARE_CUSTOM_HOSTNAME_API_TOKEN=ENC[AES256_GCM,data:n9AXtAW5k7EYh9yhenwf+Fi6vwsBE0NTjd+pTuJONYndf89zB0FencpQEP+JNMgZGRpdl+4=,iv:miaXkwVQPr9+LgqNh1QkHvwXKgbi2IawK3QacVDH42w=,tag:aRL7r/q0CjJ14CG3bt9e5A==,type:str] +CLOUDFLARE_ZONE_TAG=ENC[AES256_GCM,data:4FN5ZZCVGK9eXwYevpuWhCOXgO0iE4dYxz0I5UX37Tc=,iv:pahQjwtiHR6HCu0nMfFuzC6Y7dPXfyENGPsDp4FF/jA=,tag:0xuCSKMI1XDSIOomQAyC3A==,type:str] +DATABASE_URL=ENC[AES256_GCM,data:KXRV2rYpZln+pb3F7PlNMG21+1Qk7qUZUMjwfFPcxSO0AzsEctLD9A4ZyLo=,iv:ptpPKqrpJyW7wpXRooqLTWDVRrl4Sa21LRKlyxcPSHc=,tag:q8T7cry+7Wv+QDJ9Vxlwrw==,type:str] +DATACITE_DEPOSIT_URL=ENC[AES256_GCM,data:bxrtsEz/LbtrMDRVpoNuXh6qFb7+KOgd5JOlZ1gmhjPssw==,iv:xidREdLPnIEE+TtnEpU4yB5TBQTkOzP3q0sfA+GrPm0=,tag:EizfQYTTkDTXnKGoydh3lA==,type:str] +DOI_LOGIN_ID=ENC[AES256_GCM,data:H+a2/0l8,iv:8eeSOfbSSJbArhUnqh/tH/Eg8MEWpyJjfKdOy8Nluak=,tag:axePzXbzf2em6kuvBJ0hFQ==,type:str] +DOI_LOGIN_PASSWORD=ENC[AES256_GCM,data:rHKwdn0sFuAFVE/OLbU/e0cH7GM=,iv:CWaLzUUu0V29BWjoZ/IG2zZMopjSScn8x71o3Eygz/U=,tag:MzynhG1dVB1A+VDClJCIZg==,type:str] +DOI_SUBMISSION_URL=ENC[AES256_GCM,data:OoR7I5G1ioXq+sfjq0ZYVRzYuah8kwIxI6fL3/s6OvNQ50J7WW9g1VY=,iv:oX92Cnq2pCvr4cvIGgHf2TQ1jaI0JUVOqD3o3MGOKNc=,tag:QKuS2Xj7vxGariGXed7duw==,type:str] +FASTLY_PURGE_TOKEN=ENC[AES256_GCM,data:xMj9JrriS1bkdPw4RFe+5UXXhMv8QWCo9C+iD4v0PU4=,iv:n2pLlAhlDC4n+yo4iavkA0ef0UoUI38jtBfw87umr+o=,tag:oYF+V0av19ArwWoiEvV5TA==,type:str] +FASTLY_SERVICE_ID=ENC[AES256_GCM,data:WZOu1cwBEV1Qq1aJ09e0ApPOpWSgaA==,iv:6+r2yXJnbcwgT6ZbHNj/MsfjalmB7UxMK6hrqBF1+VM=,tag:mpRvuDv0UEixJNBVSYLopw==,type:str] +FIREBASE_SERVICE_ACCOUNT_BASE64=ENC[AES256_GCM,data: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,iv:0vkeU3zVII8G33Yq5s1zXQ903bVJaWW3dyaoJW4hDeI=,tag:+thSUh65NhYkG/CXXxCNpA==,type:str] +IS_DUQDUQ=ENC[AES256_GCM,data:I3gT0g==,iv:lO7UsKsKpCjnztHdXXVTC9iPBAZyLyNB7QxYmsbkcYg=,tag:UIfe70DBbgXzL6H/2VubtQ==,type:str] +JWT_SIGNING_SECRET=ENC[AES256_GCM,data:wplKDSLgQSxB1+Jr7wM+CXmjU9jLqkOopPFcUcJlQP/jfw/GEp/cebeCx4jjvqgfbGlAUU8GMAg+RlPW6X0EcL/GnE0huBsIcriPv4CkhHrZ1pRfr/gGW2iPUuYMgHd+NiUS2zpKDF2eluKbHzUZuaH5a3MjieBwfNSzaKek93tI5xU8pdvV4BFVJj/k1byt2bMJf1/UysY5f9POvTGrY4U78IO4w+sypwumwfiEdxOrKDKTwaFHrxHczSDrtE+WA8/aDS5LfM/NmWA+q5NlDxHDsmqe2ArNUHKKosKjWP+IcNbqZpT1IrTLssX+qOe1Hbu8y9EhJbrvDaRd1rr6bVJ45i/akVR6zN0b80ry3MkMkRXZJFFmeQhxGY1x0AV3/vIsuoi5FACsgyyaRHMag/9PwSchhuLEOxKLhMQYUT27pb7XIdkj/ZkX4miCHQUjxcLPkrpFAgfvK31VhF03ZHJglZQg3yYVoXLrCGh6ePTps4JWMRQqOkkp+XU8DiQE9mwno6RxB9fjbeNWMe6Vk7DfkfMWIsKZmedmS/PO/hLh0KXi9BOWrk29V9s1arqoWvDltN3/dVjMoG7p95jLefggBl52bkX8lBbFZf/rhaDPjmacSkV6b6rhven6t2d4RSp3BmLmBE+TJ0xMRI+UJwzCIzOS6SfNHbeRoPgVxHJTlxwP5DmBn678M+y7HxPiuH5u48NE+a6wuJQAEYzvlizKdlzwsbMQ/cQ+wATzJsAvjRcMtAz5hXvinGQGFlnKd7iKhnBL0zJEHxYfX5FHHjp/3Tnq96RB+esMFSxsHfdcDKrv0ErMqmjGrzSKnWKbCK7tYcaAlHf3Bg+YbJGkMfOQnLO1HZaJ+JoX1gmIsZxJXZGbIbpNCd/lgwYS5RS2EezYZYJhprcVYOfSzsxVKC6xRAKdzsui/ShTbCaBkAviKRTNcBM2oikMBfo3VENqNgWK7Cl8K/dIvoYd5RrPJ3AU3VnX2R4GA3lm6yYpwpGlHAoRT+UJpGWicDEE4wA98f6JIMy0yE6/zSCgwg46oN/FhsWEevGYpyFVs9R+iF9FYP29+TED7BRWQ7/60uGmgLCCh3XZOozocoa7sDEC8p2jFntVGG3M90lCWeXeOCYLg9OesV58pyKSO0DsCKX2AA6etqSXk7Mfl9U5drcG6foEN+XbERFCrIe83jNg7jy1ABSQVNH9UUJtDZDONcvpxkKLzzcMJx+5ncNU4Ylvygx++W9M893f+XOlpCl+AMPTJFYahMZeSZB08JkOE9HvFvHoDcglyxhU2Kbq+lh7wqefs+V1xIrANGF/YESMStKFamDRRDFhUVcTgmL2JteiSARZ0AqyPOPpHT/Nv/YdcA==,iv:ZRVVVZ0ObLd2AIBw1Hn/rPK2TCHj8nmL3QgYYfhJAkU=,tag:G6p1IVkf2mWLUD0GElXl9Q==,type:str] +MAILCHIMP_API_KEY=ENC[AES256_GCM,data:iDPEgS38x66DsYa+jRXpeG5eRXhUHEtF2k6T4MEHYogbicGw,iv:3YrodMu6mwm9sC37P9v6JmWiJndyzrc8ssqeZh+VvPg=,tag:yNYNJ2iju8N+qsNqFbofiA==,type:str] +MAILGUN_API_KEY=ENC[AES256_GCM,data:z8dNGGubFPmC8wd386OIPGeiY/+vXG9zKwgRcz/jQGbKyRah,iv:6rm0WQIaWw108bvkYL7QYO9bbeb/nloNiMbbwDWCHQk=,tag:L1xL0sxq2KVUBptnI5WRaw==,type:str] +NODE_ENV=ENC[AES256_GCM,data:x7Ku6uMqepgYeQ==,iv:yU1jTXY4XEzXG2c2Md+hCmuXoMsho+6HfKBJrsDmudk=,tag:+LQXQ4Z2SPwNiOkKoC6vXA==,type:str] +S3_BACKUP_ACCESS_KEY=ENC[AES256_GCM,data:iFxK4LS7S34W7w0s59M+pY5nq0Q=,iv:PORrWifuuwmcUxdQWp5qJm+VWL2BBu84oQiqEaXHlEU=,tag:eqsobQyo4T6Cme/cCf5TkQ==,type:str] +S3_BACKUP_BUCKET=ENC[AES256_GCM,data:CpvhJb7os8BwOek=,iv:fbCpnt/x/3OCGpvgAKQOk5gV9q2XjFGlGM6UVID/q2E=,tag:UHoCDTEnYjzgMA5ZUrHI4A==,type:str] +S3_BACKUP_ENDPOINT=ENC[AES256_GCM,data:oC48z5/hK4TG9H+hrzusug56AcNiDlPsjUwtKaZyUxxN324=,iv:OSPusjgVww064vyYaIk3UzNEhnPKF1wHoKjzVbOH9N8=,tag:2+3RPkNPVHVFRTOWD2ExGw==,type:str] +S3_BACKUP_SECRET_KEY=ENC[AES256_GCM,data:yQL1p4wMhaPe3aFMhSS7P7TResroGf0fSDFayaYetde86piUTzrKzA==,iv:YlKdb4uC6gk/1X2cqNp6CVIBSF2DuJ3S6vIeOPYKyis=,tag:RdWkTuJXuoaT86LGSY/juw==,type:str] +SENTRY_AUTH_TOKEN=ENC[AES256_GCM,data:w7kW3+c6GymBWpgOrdBIEaqV8jfom9+gtNBJCd0Xz5LSylEY1J7/2PfoC5UzJ2/nAQbHzR28TH6106NBpn1yjZYHets0iCBc/Gh9sGjB/weVC051QxVMCsScn8B+G0Iu1OsK5zCXaga2Z1Vh9MCX+jZ6sap5tr7RZfS0yqdnQ3zT5JntQ5fMt015i1J6z/82FZ2dvk1H96tngPVnHedQik0evZbe29yWTLBYj3PdbFYikQJrZqDx08EHfQ==,iv:vsGciFBwPh/ABf1KRo0pfhEWWVxHlZVtz0jbvJdCXNk=,tag:3MdVkwN3VSiq/SqgyHJhzg==,type:str] +SENTRY_ORG=ENC[AES256_GCM,data:tkNj,iv:0GRTxN6wBdSaqokikV6JeWev+HZyVPWMH8laAu+jeME=,tag:rJm+JegsbwIZilwGGk+tlg==,type:str] +SEQUELIZE_MAX_CONNECTIONS=ENC[AES256_GCM,data:MuA=,iv:zw2TwUG/5X5abcH2HPJtFqeXH/OQi7WtDOV7g9NVRGY=,tag:gdqqAAsM5DV0hIDrKSkkVg==,type:str] +SLACK_WEBHOOK_URL=ENC[AES256_GCM,data:WreLw7pGmv8qxhdduA9nbRRJt+53esDQiwGnDMXot+590zRH9lLFwiHm9Sf2QrdQV/pZ+hDQiyFxhhWGZi2ONh/uUlUsv1rHWz71Sd15dw==,iv:Z/Nldg2RsdxjGECfYZV1+8jlA7t5OPFgv9YNhDAq4kg=,tag:01gboyS9GrQ2Cf8eZv66yQ==,type:str] +SMTP_HOST=ENC[AES256_GCM,data:UpVcSGJZwtbHvA25ieVZPrPo5DGn+E2+xlV5SOtyUTVHDg==,iv:O6ZkYXhwSc1DJ9P98Qnwf3DjyfctkvJ0Dfh1W4XS7kI=,tag:rW1xYl3LFj1lTT1UMIPjlg==,type:str] +SMTP_PASS=ENC[AES256_GCM,data:son6HXVSHIe3H22kfGzZFf8ReB3v3/sRvT348cLOMyITaNG6gAqbHRGMTlk=,iv:cWcEhiW91uLnZwKUBkp3zqASMfa6KynXnmUgaVQn+e8=,tag:uTi+QariqNBbDO/ZRZ83Kg==,type:str] +SMTP_USER=ENC[AES256_GCM,data:nvEanRVhg0V3rlFauxom/pUFooI=,iv:3gHIsN2Aezv63DQrUVSZLkC6HNHJrvu9jKdY+LzLzys=,tag:h0OQPGZRR82FnprQMIOFPw==,type:str] +ZOTERO_CLIENT_KEY=ENC[AES256_GCM,data:SsdUq5kZVpXDdRnJDESp5hqeI20=,iv:YlyiQ5bTdZv+lZINJeLGqjScDyLYoREZ6RFca1p7by4=,tag:mnETHj1pjyFLQcVkDOx6Pw==,type:str] +ZOTERO_CLIENT_SECRET=ENC[AES256_GCM,data:cyAZ+W//AhcZbu4tRN2edkrEXag=,iv:2qaM9SVwqi0RaSl+YjH0Uzl4oZ6qPNgA4EDbsl3OTPU=,tag:g+qyzL+wj1cvuyfko3Q7tw==,type:str] +sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPWWwySXVBYjZXM3ovbG5T\nQ0hqNVRwOUltYWttVXd4ZUpOTUdTaHlSSWc4CmZhL3lOeldFUUIxdEw4V3liZGdX\ndEtjYlZOWXB3WDZ4emRzWU0ya3NSRE0KLS0tIHBtR2UxN2F4bjJIMGVJaXhQa016\nQ3NsUE5FWmZCb0F5eUd4RWV3ZC9oWkkKkwnqNH9wyYMkTxd/a+2JG1KnDxfvy9nU\nRKDAW0TvzReJ7PFDrKZ60yCIRN4w+I9kd/ZR5H5V2XIYUSqfHAtSHQ==\n-----END AGE ENCRYPTED FILE-----\n sops_age__list_0__map_recipient=age1wravpjmed26772xfjhawmnsnc4933htapg6y5xseqml0jdv8z9hqemzhcr -sops_age__list_1__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwSTFEbFk2Nk9SRlBmUzFD\nWmk0TUs5YlpBWTJYMmp6V01XWkFHYy9BcXhVCjdScGx5RGhUcFBUT3h3ZGI4d1VW\nMTk3OC9lc1daY05rTlNEcUFUYVZIdUEKLS0tIHI3QWpoMmJ3SXB6cTN6UnIrQ0Zm\nSGNmSS9zMmEzSS8xUGVDQWRhTlNxd1UKcVnda4INuoNV17gA06mJx/ivJo985nA3\njuyhB4IzbbolUpyFC3MkTaICh06Jpk8s9QJh/RolV8vsA23bkZLh3g==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_1__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiS081VmRmUmc5UTV2eW5G\nZFJ3ODNTcFFZdWtMd2xxdjFFYTJYYVVVcEJjCk5xSmRFVG1EZmY1bnNXeWgxazND\nbmpsSW9MdXBmOStaV2hIWmJROFNQaG8KLS0tIE84VTE5cisydTRHaWR2WlhlN0Jj\nSXUxVjFJOVNSZ2prQjRmaGppU1k2b3MKJl0AuVBkQQ5Hxo2l1ZMEtzXh8vwVtcGE\nktjdYaqc6/xhM/zvt5zi+0RvB9mbopnFjyNwyQhw0/Nq8Hv5EZLNyw==\n-----END AGE ENCRYPTED FILE-----\n sops_age__list_1__map_recipient=age1vhftscteyrwphx0jpp0yl60xxrjs77jq05mkzv88js7ckc926vcqepp2cj -sops_age__list_2__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2KzlxUUVMbDV1cS9hVHJ2\nK1ZnWGQwL2ZxaU9mTFN3cVdtV284RGgrUEI4CkNjeGw1dnFZbkc3NHdnK0RyQjNQ\nTEJMVm0xMFNXNWVadUFpbEV3OXhsV1kKLS0tIEdKR2h3SzNTVHUyaFJQK0ZMTjlC\nd2hTRGtZMldIUFQzWmhCNjFuZ0xvMnMKXbslP14tBhAfydtAM6eHlYwkNmAyLUkg\nIymvxwqge07HTDGS1PER0qncSPvaW2KK7YKLUTXtxvwtYsmByWINTA==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_2__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4bFUvVE41WmpWWVBTOVQ4\na0tnYXZlRFpVNExabGR1N2ltb2dhOHpOd0RzClhTdnVXeUtxZ2xTdzhoVGlSaDJ2\nWlBXSFBqMHh5ZmxmMjU1NUI5UUYyV2MKLS0tIE4wN2JlL1ZYb2M5c3BUNG4vcW1R\nTFlFQ0N6UFlIUi9JV3FrcU5jeFhUUkUKDT9w3/0ebZK/BLQJw7e5lfdHjY/rUMFC\nIpl3GtaCKWuMdc0pRgdq6j/2x8tiRotT64Kqr9lWkvuokP7yaT+mhQ==\n-----END AGE ENCRYPTED FILE-----\n sops_age__list_2__map_recipient=age1slx6e48k7fre0ddyu7dtm2wwcqaywn5ke2mkngym3rpazxwvvuyq9qjknk -sops_age__list_3__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlTDY5MXZnTWFGK2JkS2dn\nQms5eW0wQ0RDRzZtSlpPb21zMmNvZEo4alI4CmVyVm16M2FNRWhnQ3dkbVhaQ3Uz\nNHpTNEU5V05BaUlHUW1xSDZ2UVZvMHMKLS0tIEN1Njl2SmJOb2dKVmtva1pCVTZj\nN0hYbkdzK1c3c1JwalZXampacGxuMUEKX3mXLu12BW9W4HGEG9vxNbBOablAdNj4\nO97XKRqP3dstHRAp4i/JQtmuO3QaEWFD0a1xwsJzVyPblK2map79dg==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_3__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4RjNKdzhkUW1Bc0J2bU8y\nY1d3aS9TY09hM3RBMThrV0ZjYUFNWkxKblRrCkFMVFZraFJKMmJiM2I5bW9hV1Nk\nQXVENFptcjY1cWladkdtbTlNbTNNbGsKLS0tIFhOR3RRdEVDdHR1TUN6d2pDQnFZ\nVmsxMFd1cFBYa3NSMHJnaElpaG1VK2sKjcGOWmvj7PzzFMYJ4udGqv16kisQturF\n78p47aq3rzrJuQTMLv6xGG9a6GD04lLkYfEmky7+TxRg72OO3n60RA==\n-----END AGE ENCRYPTED FILE-----\n sops_age__list_3__map_recipient=age1vfhyk6wmt993dezz5wjf6n3ynkd6xptv2dr0qdl6kmttev9lh5dsfjfs3h -sops_age__list_4__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFL3VLWTZKdjJSTTQwT05N\nWXUrQzZWYWhrVm5EVGFha01JbThnVGZaRnpnCktYR3FlUWJvU0R3aGt5QlpOSTZO\nV0szSkI4VlFOaFYrSUhYdm1JYVM4aDgKLS0tIFpyRFhWa1RML0d6UFJIcXowZUFU\nbVNmUHlOZitTdTlKS0RaaFhpeWcvS28Kjs0IMQQw96GYkm1+dZXmrrEugE2Whugt\nNnoqZ1YR1vy36NMyAMpRk3D5dQHVO6VRMAP3Y290uEjAmFSmgrxuGA==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_4__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpSTlHam9aNFBoTmsyM2NH\nenk3Rm56b1BCTmZOVnRYZjZ3UldYTjkvMGdjClJEVzR3UmVPMnM2eURYbjZkZEpm\nWHJsYlFRd2JXNkdZMFhQanNLRTh4bVkKLS0tIFlDdWhMdDNzUkkvMXhZR0JPUVlx\nWVlsRytLNHROTjRPNFlxc0NwZFA4YW8KQTpmxFx6DipHgCxxsKoLQ2CX8nKSRkvY\noSl5o4a5TB6ARq75kN0Kjz6h/Cm39Ua1SxkYG8VVdKt3IpHUi4s1fg==\n-----END AGE ENCRYPTED FILE-----\n sops_age__list_4__map_recipient=age1jwuvzyghfer7rx3qtqa4vs0gxyff0sg6pqgmqvp5zlhnpmvrkdlsdha4kx -sops_age__list_5__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5T1hQaEVsYldzZE1SSWk3\na0l2R2ZsTFFSTk1QTzhPU3NYQ2h4OUc3ZHlNCnFEY0dJaHo5UWNmQ0NyRE5tYW9H\nMTB0RHJNRmdEUSt4RmFOVzFUbEZBNTAKLS0tIDJiVHNGS3dOeXIrRTJtZko4MGdY\nekZmS2tiRGdvUTkvbTdaZjVqbXRPYTgKTrxcd79VwTMd+fFe1cjg7wHIU3SWsoEX\nS5EsvnJD6GKKmGThDQu/m1EL5ek7s6ac6dVCENdQpD3lf1Da/dFcdQ==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_5__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwNnBySzhna3UxSzNxejk1\nZUl0RjhRZFhUNU9vUjBteElkbXZka3lRZFVjCkxZcGtkVFlKK2V1VmgrYjdBNTJO\nSW03SzhESlZYcEcwKzFUSEJKeFdiS00KLS0tIGJyTjIvU25DRTFuRXVmRExIWEI3\ncnpRczdvK1JmZWtyTGZuQVQwT2NFSHMKY3ExsBhxqSmZLQripZlzYwXIW604NxVp\nIzIw14rs2hrb45pWLwh7b/kINMblF8NzTMFfQbRuAPcTQfhSC6BaXg==\n-----END AGE ENCRYPTED FILE-----\n sops_age__list_5__map_recipient=age1pgxk292zq30wafwg03gge7hu5dlu3h7yfldp2y8kqekfaljjky7s752uwy -sops_lastmodified=2026-04-17T01:50:40Z -sops_mac=ENC[AES256_GCM,data:xHS1vmSEdP1dN8u+IPVQEBdeeard+uhEo4cpO/Sw1hfhK2aEhDfKfMWqZNUgLz8K0r/uae0DOrgOkKy84skDy0dX5UN/l1Rj4RkUN9+xR/CgCcTBgmghNpV8KNKvd8ixZ+cyhVW2ay1mTURQy9LUQ+UYQwBIytjGm6R/kTl4xh0=,iv:nQkHwHbs5btQB/5KSQ+sBcKux1+YpgjOrFha4+PIW7c=,tag:EbHG8oZKZeeC8fcTKi3dLQ==,type:str] +sops_lastmodified=2026-04-23T01:06:45Z +sops_mac=ENC[AES256_GCM,data:40hhQM+O8ISMPVm034TG/R0TCz8/pqlMCKfr+U0LICUP+HwV7u13/jKW1fGkUKvHeY14o4RPKo57p8cfK9RxxTMJqBsCRvLvAUp3/eHT3E9C76oiwnzTcKzHnJ0b2yfKpWsZ+R4yX8UF4IKffAEuxJgvOUJAWTaSzuX2MFNfdX4=,iv:AScITsWeoN8h0zj792K5LivhA8mA1cZNvJhQHe185sQ=,tag:8kEMmOGs68j2GlVn/7sUfw==,type:str] sops_unencrypted_suffix=_unencrypted sops_version=3.11.0 diff --git a/infra/.env.enc b/infra/.env.enc index 9dc0f4583..35419daf5 100644 --- a/infra/.env.enc +++ b/infra/.env.enc @@ -1,52 +1,53 @@ -AES_ENCRYPTION_KEY=ENC[AES256_GCM,data:wOMIg1aWk8tlzjhhO5Lpbd7d1owjoSNs5hgUSCSrnh+oA+Mr4Dj79z90hvqoMKqHrniyIp0nNZEKz12s1EMgdg==,iv:371gh6M7xo/UXrhV7nYH8bzNp+8CrmiL80u2wKj7LkI=,tag:aXsEIjb5uB4wTAxEQBNBww==,type:str] -ALTCHA_HMAC_KEY=ENC[AES256_GCM,data:v/uPIvGsn4dsz7P58iWcSLfdYR3PjZCpngdVyvEeEDYmeWCjHT4V8IJw4C7VDMUV53GSDxO3Qjz8XjeMyIod/wWHO2PciE89qXWY1Ekgdvkk8M7C3MPhMX+kaFffWbdrlNmld1svTgQnLF3h7fvQ5B5CXyzNAkT4zW2DlXRt2R8=,iv:8r9cmPUos6lc3J4x039gk11wW2Ktq5g8RqFwlxVCylA=,tag:Mh+WL7Jt2C3ZkyI9tCEWMg==,type:str] -AWS_ACCESS_KEY_ID=ENC[AES256_GCM,data:fTBVEzBLyBRLu5uT92B4gCEWv7I=,iv:rvjuN5eT12LJy6QXizSK5tMg2T2rLqd5c6T4nLv6GXc=,tag:DjKOjk536CzOpQXE14Yeng==,type:str] -AWS_BACKUP_ACCESS_KEY_ID=ENC[AES256_GCM,data:51pt7zKJl9ooUQpLJ0wAOlzvQbQ=,iv:lOVmJ9R252XxBLVKRfPiIP8xNbVqqSTJ2KFjEukYddA=,tag:laQxivbj5NOkafpmzBaUmg==,type:str] -AWS_BACKUP_SECRET_ACCESS_KEY=ENC[AES256_GCM,data:9nxYPmXFGRURhsR+yhMrWoIEbEGiGbJ9kBRBV0QyuW8kQhGLva5SgA==,iv:IiA59eTr/C/q08ug1XWRzU4CvArI/fc2LxRPgLqE2lY=,tag:NIbi/N72f0YEkUwYVFb29Q==,type:str] -AWS_SECRET_ACCESS_KEY=ENC[AES256_GCM,data:3FJv4GQur5lC7xjxLRoPxIurMJdMlMByWpXTC7k8KGlbIfgj4zpg4A==,iv:xmDUQxx/62DiUx7RFi7SL9kgFeLwmIBkTg4coVffGdI=,tag:L5U9rlxpQuAzHeEHv8YVlA==,type:str] -BACKUPS_SECRET=ENC[AES256_GCM,data:bqVQ1xn8KxO+GjS5U+p3QgHe78iEEZPTjNdMIgI2UedVRFX0fbfbWJ3Tn8I=,iv:9JLw8Gq5fVNxAtd8sR9IiceCy1b8dsuZl//Y6xECLs8=,tag:pHa86Drm4JWSVb17LUw8kw==,type:str] -BLOCKLIST_IP_ADDRESSES=ENC[AES256_GCM,data:4+QCgLeSheS+IWUnUddZLZZQGuXb,iv:C0iBdMPChOl3gre3xNX+cfMkMk3jigFKzoY6+q5bY9Y=,tag:m801K1on2hCHwEsFQSYQoA==,type:str] -CLOUDFLARE_ANALYTICS_API_TOKEN=ENC[AES256_GCM,data:P63Stx3oT9IJsADzvMUvkle9uNCK5/P1rejjS0V4gz8mlpfa32zFqgxuULlIR1Jh2z5xIwg=,iv:3qaAqRkVAGrQIYRdfcfjz8cTcix7s08jBypCOj8XXy8=,tag:j8zcl2e4PeDBfMM2L5VBEQ==,type:str] -CLOUDFLARE_ZONE_TAG=ENC[AES256_GCM,data:RhX/cLPE4XtW6xSdk3jpNTHz6pUxKTIeRJ3p0TRYdk0=,iv:f1OJXofZMCUp+GMYAV55uQFqHwO0p96H14AWuoxurmU=,tag:BKPtDXQXgrkULDrPkDLJXA==,type:str] -DATABASE_URL=ENC[AES256_GCM,data:PBQqLiZUC8a6/bfIDnhDHSWkKRsJBww0RaWP9uKDaOw+WQLyyr3K1CaQl5I=,iv:4GwGDtUHGN2UytUWflSFYNUCNcoL56GNKSGwCCpPMGk=,tag:uoxjh6/vrAZuDpg/RoJvVw==,type:str] -DATACITE_DEPOSIT_URL=ENC[AES256_GCM,data:eM0JklGpEUSqpGyBRkedf2m/fEPWNtku7jO8nX4=,iv:1J911wE5EwYhG/3JnyFE6z1u0R0INw+9MWLFOBX6wD8=,tag:faXoY8m6ohuZgtappLKo0Q==,type:str] -DOI_LOGIN_ID=ENC[AES256_GCM,data:3aDI9/Ov,iv:sOFwodosVRmb+CPEEgdfvn2L2OEmGKFJt0YaNqh9hzQ=,tag:Uyef1PgiGtwZYSsHtNJPWg==,type:str] -DOI_LOGIN_PASSWORD=ENC[AES256_GCM,data:lkm15EL+IUxwQD/zyF56x9a1QIY=,iv:nZLOYqtAZPANZW9qMMNNCRr+i2Y6wugBGDxjoG6V5Iw=,tag:UQ7rL1c6BXHO1b7alCo/0w==,type:str] -DOI_SUBMISSION_URL=ENC[AES256_GCM,data:SL0b82xVMrYfrnX/wHP8f+06l8GhnCR3E6+BF6wTNDUnd/ebqda6+Q==,iv:eQsL7bUvBRgNJERnN9u6WFjAlwgJXRCDMmqWZ0vO4AM=,tag:maHCynGzTVwiqLX5G9kg3g==,type:str] -FASTLY_PURGE_TOKEN=ENC[AES256_GCM,data:vDzES3viZkcKjLki/43j3UTF71sTDScakjyu39o1J08=,iv:5Ps9lROIbqORKs6TG3FBKmzfNtcMHF6t/uNyh0rWaV8=,tag:f9DRFVlSLtawJOqhzIHraA==,type:str] -FASTLY_SERVICE_ID=ENC[AES256_GCM,data:k6sa6eQbUOLt9IA+ExKBQ7J32zGwbQ==,iv:R5q5hzHxRjliKy8c6bn9wRUiWA1r0d/Rm5RhSSL2JHg=,tag:rD4nIL21zkkdDFQB9plpNg==,type:str] -FIREBASE_SERVICE_ACCOUNT_BASE64=ENC[AES256_GCM,data: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,iv:ug4SYwp/J+AratbxwAhjvqfv5c8u37rUtAL3ylc+wPE=,tag:ozXsWKRjIKscopX8YJzZ9w==,type:str] -JWT_SIGNING_SECRET=ENC[AES256_GCM,data:mcnEE5ZiDvfuJC74zi60TxfOjJa2/6mGHBF7VtaFMEaBRrRnYrmBlFAoZT2w7SrCjFBOcCwt04y/d+D3Ix2xUzDLl5PM/Ia7JDWSANXz/yhJZo1fZ/o1fos9DS01QAnDWeWnFD5gNheBml494IeAxaEJJIUQJYu196YMNCB1+dA/fL+Qzu/NXf6DynCR8wBtDBr4gVF/gLqJV8IXz7vfyacYR9WGC1fnmXl+6oheMz4/xH75QWAo2MD8RBUTHpRdu1RPuwa5IPcZFW6nX5GSEnRgh8YY3KfM2X6oHoDGLEofDmtc2FKR1mmOFOR/AC/Hjkz2mLcTpcqiM1cBBQj6c8gZdp580mpgFFpMCHeY+9hAXjVD9lnv4d+mK7HRVCD02bAUL8txc9cGXouj35ohAPAR9/Ya9QVr6h/rX7HNiIx/nq4zxWwHI/IpIvUo+KMUXCWubgNHOaf7OmKftkKQaIQY26VlDoGy2Yy9DLdkt5ZSPSIw3516wj14a0vxTvhqRQVgbboPSuK5RdHy9XyiCosToo1nyBk1UaUX0Aiw7p+5qA/9JhgHPQQawTCymAS39T2xYKHR4LqrrIGWMEiRV8RijSEr9/6MuSG+XPrnTf3CckMO/TW8BqeTKBOGTMw8ZsipHBGUvv8otqy2CCfw7dWy0PKgBVwXYItslGy70kQ=,iv:AoChU6VbGj4Uk+7jpB+aXcyWPzPeIRdrXwpIV9CmCdA=,tag:82ZVmzjs7JCwY3pn/AWkNg==,type:str] -MAILCHIMP_API_KEY=ENC[AES256_GCM,data:a/thucTbZdR/nO8ItCG9ghWMibQ5mJ7A7onFEbwk2dgCc3zZ,iv:2/1lKPbjqVYPkKSH4PrNjP28ZaP7Sa6hZZ3or7UjqnA=,tag:/Y7QhkLsZV3ueBgJ1O+nBg==,type:str] -NEW_ACCOUNT_LINK_COMMENT_WINDOW_MINUTES=ENC[AES256_GCM,data:YqI=,iv:lSBi5o1bN/BksyAVc1w6dKo1GTIm8OkdH9EXnPDHUWM=,tag:k0trtJ7b7EbLdiE8vSyo+w==,type:str] -NODE_ENV=ENC[AES256_GCM,data:m6W3VlmiodtdOw==,iv:bXJk6ja1uBBbN2bfHUCVpUZTDOhsBDN+r1Nkd1XN+zk=,tag:nxey2MQ2Pk2w73aJlfWTcA==,type:str] -PUBPUB_PRODUCTION=ENC[AES256_GCM,data:41lUwA==,iv:dio+3UVU6TB5Ev2e4EVJL3a9Mw7Ch1RltRyJfSgFw0c=,tag:tDWSYHoC6As4jid9yPq1vg==,type:str] -S3_BACKUP_ACCESS_KEY=ENC[AES256_GCM,data:MzGx51/ro5fmREIhWqZifXV5cek=,iv:2CqfZVCcj0VqtbdWt5I6WRuOdwXKAqBPEp4AonSrMoQ=,tag:Cluf1jDry6ugli8aoZQVmA==,type:str] -S3_BACKUP_BUCKET=ENC[AES256_GCM,data:7nEw2G4aAoFR4GY=,iv:BQIhQbOmkIJflEV4a/MFlEVQzf906wsrVT5kIUXQHQk=,tag:5FQ+1/r0zmIY42DnwjVh8w==,type:str] -S3_BACKUP_ENDPOINT=ENC[AES256_GCM,data:IVxeKBvyYpkjEP16NRGY7pUsI7q7+0oxbcEuTJEsvmhpi8o=,iv:bBT3sMNKeBsRoGlamW7gJAJYrGpqs3IyIs4UA6mezz4=,tag:UP5FIMQCIA+NL+ilXKroHQ==,type:str] -S3_BACKUP_SECRET_KEY=ENC[AES256_GCM,data:dyT1Eq216x/gmAfR6sDVhtQttBsWHIUp/7eAVFTJ7UQpQHLXO6w+1w==,iv:gzuvYFcRplCM2X5Gfm2LQgxIIo/fxxxBntNeKK00tMw=,tag:n1KisIlMnH1RE3hfDpRG1Q==,type:str] -SENTRY_AUTH_TOKEN=ENC[AES256_GCM,data:3HyD+aSAprTugHtJ1POYAFxUttnMq43JPGR3cNopNwQPC6DhNISEGT1bPXCYmCZ/plpZMCU+icQxXEKqjtTQCBGanwcJWd1AIUbWKT7PDAMK8Dlbt4CQTTgWfcH9Oa/RxISihAZzPUzh3oesPIRECq4qJjq/BSIbHbh2yESi1TjXrm0QkPvUSziLpy+yIxK7gzeyAtE26wN1BmvAX+L3KFMYqGDughE0NvA5nKiuTQNtz1nqvNcNUR32jw==,iv:dxc+/4CNn1+wb+Nep8NoARKViuth0YdVEv1+FY3NqWk=,tag:JfmTjsytMmjNaRLYa2W1jw==,type:str] -SENTRY_ORG=ENC[AES256_GCM,data:6Bni,iv:gnRhAzWqW93X5C6KxRetqXDAB08yGu/dIAaJVFNa/bE=,tag:Fyl8pgQL3y/HDgJVGzEgLA==,type:str] -SEQUELIZE_MAX_CONNECTIONS=ENC[AES256_GCM,data:Ifw=,iv:C5N/BSca5304jk1XmRmDnUoPOF5I080VUa4Q0faSt6M=,tag:ESSWOE3839ZYBJLjTYrfIA==,type:str] -SLACK_WEBHOOK_URL=ENC[AES256_GCM,data:sRSI/Y0yqd8CEMCVsXO4Dc1dIH/deWCB+RmSUb7cw7eOjpSXtPeMUFGmVz1KrGZwHlz4h/vLmGCWcGxSP641DJIdjQONzw7RQznCzdYzXw==,iv:CcgsAqkfAIFbdRkSludMlMr1tKexTxmAf8OlGOMA/B4=,tag:WoqKTVyyBam/GkkRZjcniw==,type:str] -SMTP_HOST=ENC[AES256_GCM,data:HqWe1tf6ATBOXU+JE4TtTbexv2oGvzf1o6G+IHvb4hC+/g==,iv:JCL9nySZL8XunQlxGyekSVq9KWtoCj/Cjh2mSYTKsgs=,tag:/a0i3A0GVzC3fYO2OcSJ3A==,type:str] -SMTP_PASS=ENC[AES256_GCM,data:Jux/UdB0zSMemT1zkPj/wkmIvTFZRdjGZT/8pes9lsqi8h2NNpoyze19tkw=,iv:3pusGhqOTsTkHOYhPSKV8llvTQjzaRdClQd8qiPpbwo=,tag:bBRPamuQjJiKDi4erjh0Ug==,type:str] -SMTP_USER=ENC[AES256_GCM,data:RChdPwFxCX5OOUy+RBvdouPka58=,iv:sKjOjgKvDa+debdnjjSL+on8y0V2O1Xpzic1HbdZcVg=,tag:XXHmceVya6P+1lDR+zkObg==,type:str] -ZOTERO_CLIENT_KEY=ENC[AES256_GCM,data:JmrDfAwVgDG65OwnMv1NmWZM+EU=,iv:GuOvVX3AazMIXUZed15YNc56zR68oBbDmcsJOrplFDs=,tag:lvU27NlTDYO7Jnnj7h/Szg==,type:str] -ZOTERO_CLIENT_SECRET=ENC[AES256_GCM,data:giST24Yf5Rkt9KthzTSVQlHylXk=,iv:lZCIEna4MQV5JRYAx2aAK5AzGUJDbajElbFLkA4ix+A=,tag:VbNtDR/Yx3HUmHxTYfOptw==,type:str] -sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzM3RiczVQV3R3cjJIUG82\nSUpMa0pTYnYveHpnVWhLT2NMa25aVTl1LzFrCjVxZW5xbUdwWlRqYVoyejdVUEJJ\nRVFmRHpUN2UyK04yRzlGeU9RZWlnK1EKLS0tIGpDNWt6bkRjbG9ydC9hSjBtVjBY\nSElxb3hudm45dWRUVlltbGJyak8yazAKf6MT0gwwoPR6jl104NoFB0MTERjyLzMz\nsq3iLSTtHuHnGpLvnQP7dpOA0AiTcT7CQdPrygH82n3Qq66TAmL77Q==\n-----END AGE ENCRYPTED FILE-----\n +AES_ENCRYPTION_KEY=ENC[AES256_GCM,data:hluuMW53I0wYxmRXd/1ehzxnahd3i9UIsccUV/0ob2MTqGW8v5XUmRqEUyTPlK/S0b+JMOnU/hgzzjdBDjeedg==,iv:GGEu2A0Y2JYZA7y4lc/FnL6Bxy/x4a2Y8lOgY2OIuMA=,tag:PN/Bmc9ZXcUnFCdkRXeTbA==,type:str] +ALTCHA_HMAC_KEY=ENC[AES256_GCM,data:YyQiDkYL1WEKVnpJroDO0k2t8yy0CUpJnUXZr4WtgY+b2bgtn7unKMQWICLmjWnH5NOIKnx+Mj6WrB8tSApHiWfhRsQbBFkKttf2YSFcWwr/biSYR26eQov54vdjs0mb1hvuIM0DMgv9zWgLpZnZ0ESQ3FAf9W9+sokhv/dw3Hc=,iv:IlYXY+t1SUtZlpfuNmuM/10It7iEfF5gIXjrtJ/mFAI=,tag:24K20wUZOk5qDSV5CbR1JA==,type:str] +AWS_ACCESS_KEY_ID=ENC[AES256_GCM,data:VY3VNXqx8ucokO4CufIPyDkE6v4=,iv:b9lRgqp0pheytU3aClyW8tPhRffbLZ9iTMLWlPh6M0E=,tag:NimLdLJCX7oBxENFwsSsBg==,type:str] +AWS_BACKUP_ACCESS_KEY_ID=ENC[AES256_GCM,data:kAzcia6kVaHOK7kGtig85Y/MWV8=,iv:nJSTLNIJiXIFEVt3as/s1bKd97QrH0awKTmteD+tvbc=,tag:VvOv1YpM13ItxovS4+ETqw==,type:str] +AWS_BACKUP_SECRET_ACCESS_KEY=ENC[AES256_GCM,data:LpDNo0qWPtlGGhfB8rh20MwrYpTXgoBJtt8XQmNaKJ7NKrTBYjzbtg==,iv:p17XCW7Ij/Gj9mP+UMJeSWuMT9qlJ9ZgTrIZIZ0AZhg=,tag:AvZqAFB9mdTpi7x19dIMpQ==,type:str] +AWS_SECRET_ACCESS_KEY=ENC[AES256_GCM,data:BywOPljR1D+/EwzP8suVl92M2wDmmGc7Mrs7Q6lx5Z7/jCsP+6H3vA==,iv:NlvjufjcWAPzytkzj1jMAyDs2T2tNso88nroqNQPJ88=,tag:SGZkFv9VLWdlFIcz/sSjqQ==,type:str] +BACKUPS_SECRET=ENC[AES256_GCM,data:bXfj3wwSQL7nyRQmoZFBQQTrvpVssZTKeFwmUnGPqQj5tqWNZHJ2HM+2fS8=,iv:Vs6t6hdyBKTLIfhZ5qLu+UEx8DJT8XRWYntw8O5h9Bk=,tag:stt50aInjNY9ScO5yXsE/g==,type:str] +BLOCKLIST_IP_ADDRESSES=ENC[AES256_GCM,data:27JjvxEIjulgR4VIQQ+8aLIeORHE,iv:5HwBtTXtrCgzgyLrdVCXmuUPFwRJGp/9qWnNtUkBo40=,tag:UtEuNP/fQ7xw6IMSMkDVMA==,type:str] +CLOUDFLARE_ANALYTICS_API_TOKEN=ENC[AES256_GCM,data:6LodxsaQjdDffPS3d0V6/MewIfYUEVdkN5yM2n85Aai+vICgdtrkcYHnH0ZfJ6tNGu5jFO0=,iv:He/J1NdTJFKKwgn+L9AVPNJ/NyO0QGCCfDrDZSgFNEM=,tag:lYN489iBgDs46WPe+8zgzQ==,type:str] +CLOUDFLARE_CUSTOM_HOSTNAME_API_TOKEN=ENC[AES256_GCM,data:p9I7tyTaXvE6EP4E3t3/ek3HqSrema088tC3Yo0WHCWPf4/A272ufArV0Ge+z0Pgl0HL+wo=,iv:UEuSVmyLyPGu26CMkTBJMDx4KMAV4JjTZJNNxQEZXLg=,tag:8PMayXj1Fi//JeYwAfuPFA==,type:str] +CLOUDFLARE_ZONE_TAG=ENC[AES256_GCM,data:RpWPHUg0aJC6KJf3nVJtSdfDFr4uzkLV4GjD7AIHQQA=,iv:iIkrQvZwNil2kn3+GyjZJVJ4v16CRSsW1lvahXQNszY=,tag:2wXzXDsDOfwJg7PWSKBZRw==,type:str] +DATABASE_URL=ENC[AES256_GCM,data:nKmnmOtMFKGwHpaX2jJbxWsDmPsK5vJ7vW6ACmg9EAWNa9bgMYfVPKEaHyo=,iv:FD2fIhFiAyriL7shQAC/UtxCx2qG08U/tHtfPtoRZhY=,tag:5ZFKaqvnkTXP7VR1ueEuKA==,type:str] +DATACITE_DEPOSIT_URL=ENC[AES256_GCM,data:T9OqFdn9xUjgnjZ45ph9o8zQShotmvAGEH2gCyg=,iv:JJduZDd0KfG6GU0SJ1nqs3aO0PQBBGQXgG8/au7UZPc=,tag:vc2TVXHKEUvu9rfgTaIa/w==,type:str] +DOI_LOGIN_ID=ENC[AES256_GCM,data:Gx80dcPJ,iv:TE4g1Iyf3kg1caJ/UeUTn3MhbcRNWdve5lW4izxwIfo=,tag:hJ34KiGdRtput+xWDg5VkQ==,type:str] +DOI_LOGIN_PASSWORD=ENC[AES256_GCM,data:LwGaqiYIm/5W00qaugZn0iuXiAI=,iv:tskTMCLSNlVPjwaZt71J57ecWNSpmRXdKBcfGAB1BBA=,tag:8fMXp9TMqbeR2dm+d5kC0Q==,type:str] +DOI_SUBMISSION_URL=ENC[AES256_GCM,data:AF7uka7UuScC8rBFaxjh8F1aQEcOE29/UBjV4DvGF5RWHaRzv4VS8w==,iv:kXRPFmN8ie+emt1X/qr1nfHfRPY6TvInnIIc1zW15FU=,tag:VAAj4VmttfIUFD9mJZ6lPw==,type:str] +FASTLY_PURGE_TOKEN=ENC[AES256_GCM,data:NinyR6AK8cQ+aD/4J5mEVtFRt+ll3gM3gFuF4VmfQBM=,iv:s1U5cmodes0Po3iRbhE0WeuB5Hg3nIE2BiP1G4Ci/QY=,tag:CvIaOkZEa2NBlxzPRhO/RQ==,type:str] +FASTLY_SERVICE_ID=ENC[AES256_GCM,data:c72vPOQDEngQdkht6LH7iop6QvQ7Lg==,iv:dP255TrpTbCZBa1KIMvRZtaDeQ0aH3XtXrR3k8p6JZg=,tag:FP8+mQib5vrpFFkpv5LAcQ==,type:str] +FIREBASE_SERVICE_ACCOUNT_BASE64=ENC[AES256_GCM,data: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,iv:VXnXXVyHrSq6Ruq7/gPIRseI++jlyQ58dOAJWkJ9G5c=,tag:/O/1N3LZkcJbOX0OTrX8WA==,type:str] +JWT_SIGNING_SECRET=ENC[AES256_GCM,data:IMt3XkNAoBa/GtRmewiP2g2nBwJ1Khe4AZd1rNJgk8U0y16uDnGDuVoJjy+buODLY25VSrRycINeZpLGpxloy/hSaI1x+LXczYX5w5OGqCCMEqezlrKJAsE22jgo04Worko77HK1/kdW6tc+fpdCaFv+Dizrto87gz3BdOaJ6N8g1mXrO3UXmiUSZLq4KUxQvII3GuSXGZlhSFhzmZATvcx5jkMOq0TE/Eo1sEo5diD58cLrrbtKrUZNUAAmPfkkBRq2kqc92za8xvhZuMH/XXB5/oAJ6woPYkVVKH2ZyJ2Ay4PUBtN4X9YKAoKAb71ktVWdKFMUe/SW2FTY/SMQZVyxpPAX28SJL6UOJtOTR9cG3ywwHHGnCklrdoIzmegiCrLPVUJxOvXySGpkm02r7zmo9xuasIEXcs5encKLEr90pjWyceHoemxz3uWrZ8hgFMj0Z6zx2nN38jMDNl5Whh5JiFKl5gB3LC8gS/kp7CBoFxo7LWGZ/7+y8UGsIC06oG1E2htwMYDMuEu8GZiduOT+GrQGuNKwlmyofPAzExe2icp75lB2zd+a/Qm/LbawSc2Xi9KwBQo7zV39m5cztz4gelAri73frmUF6AtRwvt2ikABuvnxrKHxRtcX1Dwkb3o2WHN6SxonE1eE2hsIU2I2WC+hlYyDpg+rzSJ81uI=,iv:j19213e2OHGsS7QIBxqMANk4L5DZ+RS9J+QO7KC7bb8=,tag:w0vgAJkQuhbtSv2QDUQJ/g==,type:str] +MAILCHIMP_API_KEY=ENC[AES256_GCM,data:OpdXXII6XHC/61rfZSr5vs6ubiWgAXLDPF7eQbt6xefC3+8P,iv:jojn4fJV0w4KFy6X97aSm7XM/iOd38RYT2nWkaYNx3I=,tag:3Qpg7v03JIxEgmaB0U/luw==,type:str] +NEW_ACCOUNT_LINK_COMMENT_WINDOW_MINUTES=ENC[AES256_GCM,data:OcY=,iv:dYc2xK2JPksddyIJ1Mkq62gAVsS0JmnufsxMfEIMxd4=,tag:YAz+5fVTbFyE+7IMMdTtGQ==,type:str] +NODE_ENV=ENC[AES256_GCM,data:IgX++6hQvaZFig==,iv:AMO0hkWr+iZLD/CQmIiexEFjYx7N4agMMo0Dy6iJclk=,tag:KpNdG/NT4gaQhS4bfM1T5A==,type:str] +PUBPUB_PRODUCTION=ENC[AES256_GCM,data:IBbQMQ==,iv:wvN9Zd6fQHLqTe5LHe2DTQp84XGQCMeiNSGZKATmVIY=,tag:COWZdeNKGc/6osEqqx3XJg==,type:str] +S3_BACKUP_ACCESS_KEY=ENC[AES256_GCM,data:XSLKbLsl1khsbv+FojDtZRSfIyM=,iv:HMhMjQh0Tx7RbrrGT5x+pxrzophmblbwCg0+loGi8MA=,tag:FTy/A41YmsCjoU/3Bn7jPw==,type:str] +S3_BACKUP_BUCKET=ENC[AES256_GCM,data:GCQl6ty11oiZj+A=,iv:XG+LRGSkPn77+KYLYCFnb/TwIzW2PNnNt+CgCvjPQKw=,tag:eZYALUo9GKrlnKrDpOaWCg==,type:str] +S3_BACKUP_ENDPOINT=ENC[AES256_GCM,data:Qy4NyFuPqNLicMFaA/s5gQvEGAAPPsTMCj2Q4twIJvDFqzY=,iv:Gz6XLNEGFcB2+RXdvaMdWsLnR5GgiQ/npEUXDULOsSQ=,tag:0fF4y+UphHpv+ehoRbip7g==,type:str] +S3_BACKUP_SECRET_KEY=ENC[AES256_GCM,data:tJSp6dIeNVDqENxbpADcOa3zwKvNLUUqcPsD4UCL7d8n34M/e4VcRw==,iv:7VLR7kdgKTN4Xlsj9DfFgZ+TrU1whDqDjLi2aZI16hU=,tag:0gGnHuSCsuZfOS8DSN/eeA==,type:str] +SENTRY_AUTH_TOKEN=ENC[AES256_GCM,data:a6v0kGd7Db/lhkWi8mTI9aCe4IvtBu3APtsRw+5VRQu3bHOQe2bk6jOQ6cupGqjab9Do1HAbSw95UNRt9cdbqnReUxvgQtuTQk5rfpwbqOb0r9Genz4obiiC9kf+5K/NBMvEUhUv1uJh41pGnCXoDJK90neqPmtgypWxOIGIMgJxDMgFFxPkIgxYfIJUL1WxXRZ6GbP4NxMCTvxamPHC5YbOUA72rk23YDl+pH+yk5n8k2OnMS9P/1vQug==,iv:8Q8aJeWihdqKNkK2PgZ3NzfA6Dezv3HypnBD3OxauE0=,tag:8cyF6/FxTTG46JK1Eu8+nQ==,type:str] +SENTRY_ORG=ENC[AES256_GCM,data:JtGE,iv:fxgeb7WtDsc5Y3jYjgrbdspJ4BO9b8hwzpsPv6EDk40=,tag:CnyDg3pwpUEgwqMQKlCARQ==,type:str] +SEQUELIZE_MAX_CONNECTIONS=ENC[AES256_GCM,data:LE0=,iv:xwbQG6xnT2X4AwohtMV4t0HKfPDh71TrRrx6udCG34c=,tag:Wlza7DJ2CuQhgzRsqtlvOQ==,type:str] +SLACK_WEBHOOK_URL=ENC[AES256_GCM,data:KblZpeiu3fwhxX6Sgj72XNbW2MnOLFzFm79YQPHCRqdPpVaV7D8vyhz+CWtYLKchhZ74RRCVNhxjOmWoJkpysSgefWQwvFJSg8TwB19Prg==,iv:AHydoqDLo2veUFofFN2YZ2gtnW3Vrssu4FBBuFiE2dc=,tag:FysJIAWqlTRhvhXOiEeVQA==,type:str] +SMTP_HOST=ENC[AES256_GCM,data:UuB6ygWZ61YSS6PHaDDoHcog4cYet745asByT0XwIRhi6g==,iv:LwTYkfGRLU2o06WNhKkWdYSCl9Mpmsri+8riOGy8EbI=,tag:YnbYogOBFeU6xRR/6EdE4A==,type:str] +SMTP_PASS=ENC[AES256_GCM,data:na/1Eukw+xIpTVsCb8s26qQfKayQiWX731KBvkTQ1g1S19YBcLXe3aNkm2s=,iv:WZiUZE4JYZLye2KBOiXVCrPLBj702cnEQxSOyv+cTXk=,tag:NGf2hiwmpNEneWhpRziIyg==,type:str] +SMTP_USER=ENC[AES256_GCM,data:c/S+39nHjQuEk72RROJ9UZCOoDo=,iv:ON+n/uwVw0rPKCjwEEkQDUb5dzut8PIA2SZnpYh1LLs=,tag:2lZpOyGZpNjXgb9o6/HLSw==,type:str] +ZOTERO_CLIENT_KEY=ENC[AES256_GCM,data:hePbgAETRQ1rm49oVYLKPHGfllU=,iv:n1x14qwydRC7oy/O/Zhml61YA6/rcd5b9TiWuDJbvb8=,tag:p1okF/76n3182hrp964Hsg==,type:str] +ZOTERO_CLIENT_SECRET=ENC[AES256_GCM,data:WsJqHqmLtKr/0OR1f4bgkXwUytU=,iv:bhsvybVQOqhAExqPE8a8iCTr9x9xfDaPPymnajNrjg8=,tag:F/I1MSy/VokTyxCWyiDIYg==,type:str] +sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4T0laUlh3WXhZb2FlcTh4\nSnlTcHRXakVZbEp5dkd5TUI2aS9JR2lYM2xJCi9WUU9PNW9mb3hhVHhoZUdQTnlt\nYTFlTGQzUU9TT1dpQzRVM1Z0ZGJhUW8KLS0tIEFKVFRVZFAwcVU3UkdBWk4xeElo\nZ05BU1BQcDZUcDNObld5Wnhrb1UwclUKOR4E75aswX0QDjXKO68iwOjTIKQzl7FP\nva72KmyC/RyQIE1ZtzjC1ENIum+18PmMrD3AYMKTrt03+WNqqeVA/w==\n-----END AGE ENCRYPTED FILE-----\n sops_age__list_0__map_recipient=age1wravpjmed26772xfjhawmnsnc4933htapg6y5xseqml0jdv8z9hqemzhcr -sops_age__list_1__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpeGtZb0liNzhIenYzejJ6\nVWRFZHJEbzUrNGJKT2pyUDBmUmdURjJVVEV3CjdGYW5JZmU5Yzk4Y1djN1dZalYx\nSlgrc0hnMGVZSmlzL25uM0s4ZmZ6ZE0KLS0tIDR6dGxGbjlkNE5LbnE3RFRqNVZU\nVk8rcWxSdDBmT2EwaXhxaFV1ZlhIQW8Kuz1HcUkz4PntXxyI/+9tS53dK9WrVBwA\nTrsLBLjdxOvVKEsw75YRGVcyVQLjtQ4id8F948RwWif0N17d13gK7Q==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_1__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwaW5XaWx2cGVaZVgzMGRY\nZThDVWppeGx2Qjc2bVlQakRQNCtKaXlYcGlnCnphNEVxdUk2VTVyYjJKTDJvZ0FQ\nL0dkbW9qUW5JRUt3VHlLT1E4emFkRlUKLS0tIE9mSXIzUkVkWWhHUXJ4R1cybFBT\nalJXWnpBaW5WVUdOeUdWUmMvWGVKNVEKfwtM7iVNk4DZ/oEs3wmW2M6OWyZRE+HG\nTpOrXjwTdTWe88H6brfgn1lBlULK1nxxlH69dCT98iZcqzpKokF/kQ==\n-----END AGE ENCRYPTED FILE-----\n sops_age__list_1__map_recipient=age1vhftscteyrwphx0jpp0yl60xxrjs77jq05mkzv88js7ckc926vcqepp2cj -sops_age__list_2__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5MzVVdC9jTWhaK1d5UHRU\nZW4xMGwyVG1LU0NrYlVZamZ5bEwyL1FpTlZzCi83anRFNERFck11UlY5dHlxYVNX\nRE9hUGRJWG9NVGRRMTVpNit2OHA1emsKLS0tIElQU1VwMmZTQlJoSU1HQTlHYTQx\nUnpkT1VoREZLYVVuZU5mS1Z0NWlUU0UKRRc/vlvt9l3UW+Z9ktFg65vCyFT1he2Y\nF+7jyh5pcaE27gxkA3niqBj7nSOvZNapsXq4CaAQ2krHb8VE0A9uKw==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_2__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDV1llVkNZZ3Rab05uUmoy\ndDIrdjY2WkdnWFlqWFgxcUxsR2s2T3RacVU0CjlITkRPd1NEZnBnTVdnbjFRK2c0\nR1JwbWJLaHc5MXZWcVp6eU9XdTQ5MGsKLS0tIHJSRE56eVpoNDQ2cTBuM1JHYytQ\nVXZPL1ozZnV4VzlSVmlnUkZmNUhqN3MKscu/HRsrdw1h2Aa0X/RgvS4fVLZ+LJiF\n7CBA7uFryjExrCySttCHNCLEXalxa4FQLtpPUvaDdgZ49Zjqs74YoQ==\n-----END AGE ENCRYPTED FILE-----\n sops_age__list_2__map_recipient=age1slx6e48k7fre0ddyu7dtm2wwcqaywn5ke2mkngym3rpazxwvvuyq9qjknk -sops_age__list_3__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4Y3NpYUJ1SS9OZXk4ZS92\nQmUwK1QrM1JZL0NUQ1FIdUlLL1dQaHludlRNCkozeFRuVXVoUnFabnEreGtJRzln\nTjA1V3RtZlp3bXFEZEc3Y2NuclhVS1kKLS0tIG5xMk9YSUx4Tzk4b1ZNb2UvSFQ2\nN0tPZFM2YWZGMUhUUk9oSENCQzJ1SlkKCbQrA2CP+r1KmF3KlWhXmA2dPme8uCH0\nAyPdeOIT/ThujcuX3KM++4Cqnc2FLic/9Y6kq/QrAbdHfrz2zhBadQ==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_3__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUSEY4U0dzL2VyYU1tQlFw\nR3FJSlVYdmRMUUtFUWFUTkpia3J0U0Zlb0ZJCkxRN0s0T3gxRWppTWw3MlJ6eHVp\nei85NU01WjllU2E1cnNIY2NXOWJleVUKLS0tIGlMRWxJeDBMSlNrdjQ0ZzdRNjY4\nWkx4NEsvcEplenJxeGtOMmd4cEwxYm8KhzN/lWheILVuAMqd1Jn6BM5vLDXmbUDb\nWMPbRLMtczjwR2xWIiHMYmkuA0KemEdr4qrAAXL/sSSkXy1q5EXgCw==\n-----END AGE ENCRYPTED FILE-----\n sops_age__list_3__map_recipient=age1vfhyk6wmt993dezz5wjf6n3ynkd6xptv2dr0qdl6kmttev9lh5dsfjfs3h -sops_age__list_4__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBROHJudGg2U3BsRHdKZWlV\neUVnc21kTjFCbjVVNWwxcnU5VHh2MzJaRXl3CmNuVFdNUGMzN0loTzNJazJtVEkx\nbC9mWFR6K2ExNGxQaDg0dnRYV0FINE0KLS0tIGNEOEZmMm1SQVVSQmIwZi9QY1lH\ndGVqMXBRdzBnSThOMnBWUmxIbFlHR2MKwE21m8qGz+3EnPpB7hqKiT/vH9WsONLI\nhoz0SuudTdK3jnjx8P+orvRpkyonxLH1WljXVZ9qHnCsh9uVuz6OvA==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_4__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMbDhNb0o1OGxGWmV2V3ZE\nRWVMVTBrY24xNUdpbHJERnRoWDJWME9rUUJRCjdUM1ROTG1iTURDN0l6YThyZ0JD\nQTEzb2ZveFZIc3YyTDJaMHlzNDBMK2sKLS0tIGo3ak14dWUwdFVjdUlwWWlIdDl2\nQWJHRTVnQ3FoRlluZk04Wmx6TzlsVzAKdiY5OQSx+QwZ3TbwLweX38gdmr519gkI\nccmSX6DLTr+XroS7PsoNw3mazhhHzflXfjBjWo9XsYuHoa2eKI6fKA==\n-----END AGE ENCRYPTED FILE-----\n sops_age__list_4__map_recipient=age1jwuvzyghfer7rx3qtqa4vs0gxyff0sg6pqgmqvp5zlhnpmvrkdlsdha4kx -sops_age__list_5__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsYVd2ajhDaTFDK2Vud3Ra\ndGM0eThqUDZNUHZtUVJpNll1MTA1cTlSM1FjClFjQ0FxQThuMzFkNnhYZFp6cHZZ\ndmI5dUtaQlNQUTVRZ2tMM011LzJqVnMKLS0tIFYrVkt3MUdrWjRMbUo3R1VwRDNQ\nWFdxV0ZwRW9pcXJQT2ZtNW5UdUVhUHMKGAnQnwQpOLCer0fFGeu5ihJ4285RquKY\nuuCsA/s893UaHIT9Bcs6kLWS/8KsXfbmryDH3NBsvGDTADc8f8J6vA==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_5__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrRi9DSnJydS9zcEJYTGVT\nTmhzVW5QbnpBdWxzOFY0YWJEZWxJdzQ1Z2o4CjN0VXFGUzBvTXI0S01ScnUvbmUy\nOENHT0xLL1JqL2FUTGVHWUFvZWl3TkkKLS0tIGpKckJQbU1LcHVIbFYyRTAxdE1B\nYStzL1p0TkdsdThzeEt3S1ZsSGpXT0kK+xM8I77RZqdxtlorq8I/4dPz/LqkCY/K\nZV6IHpRne9LnVTKJiepE6qTYgtoGPm681oxrfnpRRGn4mBTygPeTyA==\n-----END AGE ENCRYPTED FILE-----\n sops_age__list_5__map_recipient=age1pgxk292zq30wafwg03gge7hu5dlu3h7yfldp2y8kqekfaljjky7s752uwy -sops_lastmodified=2026-04-17T01:50:37Z -sops_mac=ENC[AES256_GCM,data:HaHv//Fl1b3wDAN+dTEsRVz8jkNuy6/UoNStURH22X644Y42tdCZaut4Az1LiwD2dbWTawuBkF0eotI5+1qWaaGWQ5etavJtslQl8SWwuQwVX+i0zivfpVhSj/RbbRGxIaiNSHKzWwr0HpaFCYIz1uM6F2ebmeFn5PiXCAQMGgk=,iv:wJrZGFAt0aUtuOelN97UT1dy1rrpEaU437H6RKBvBxI=,tag:qeCGsU4CjfUvdb9tFfx9sQ==,type:str] +sops_lastmodified=2026-04-23T01:02:23Z +sops_mac=ENC[AES256_GCM,data:UGUHCR1NS1V+OBGPRLhR61HBspZzcHZqFXN9tGsHamxEAB5Z5aE8+v4b49aELBEqLxvAYC/VJV8c19xcysAYLRaOhH612UOSX4b8GxeFVBCiUrHGenDrheneKugdunVBAUIR1ei64fG0cIA78vpycGQ1mOmrDzrhb6tj2WeWDk4=,iv:resa0/vzRZ37Wq/J0BeEboHd90pXTXF3Ywl+JnFxeLM=,tag:5WzGNUYdkzO9h1fSIphH7w==,type:str] sops_unencrypted_suffix=_unencrypted sops_version=3.11.0 diff --git a/server/envSchema.ts b/server/envSchema.ts index 25f953c26..19a374a78 100644 --- a/server/envSchema.ts +++ b/server/envSchema.ts @@ -156,6 +156,12 @@ export const envSchema = z.object({ .describe('Analytics token with read permissions fo Cloudflare GraphQL'), CLOUDFLARE_ZONE_TAG: z.string().optional().describe('Zone ID of the domain used'), + // ── Cloudflare Custom Hostnames ───────────────────────────────────── + CLOUDFLARE_CUSTOM_HOSTNAME_API_TOKEN: z + .string() + .optional() + .describe('Cloudflare API token with SSL & Hostnames:Edit permission'), + // ── Spam / Security ───────────────────────────────────────────────── BLOCKLIST_IP_ADDRESSES: z .string() diff --git a/server/routes/superAdminDashboard.tsx b/server/routes/superAdminDashboard.tsx index 7f7bc573e..e162aeef4 100644 --- a/server/routes/superAdminDashboard.tsx +++ b/server/routes/superAdminDashboard.tsx @@ -3,15 +3,22 @@ import type * as types from 'types'; import React from 'react'; import { Router } from 'express'; +import { Op } from 'sequelize'; import { filtersById as spamFiltersById } from 'client/containers/SuperAdminDashboard/CommunitySpam/filters'; import { filtersById as spamUsersFiltersById } from 'client/containers/SuperAdminDashboard/UserSpam/filters'; import { getExploreCommunities } from 'server/exploreFeatured/queries'; import Html from 'server/Html'; import { getLandingPageFeatures } from 'server/landingPageFeature/queries'; +import { Community } from 'server/models'; import { queryCommunitiesForSpamManagement } from 'server/spamTag/communityDashboard'; import { queryUsersForSpamManagement } from 'server/spamTag/userDashboard'; -import { ForbiddenError, handleErrors, NotFoundError } from 'server/utils/errors'; +import { + addCustomHostname, + isCloudflareConfigured, + removeCustomHostname, +} from 'server/utils/cloudflareCustomHostnames'; +import { BadRequestError, ForbiddenError, handleErrors, NotFoundError } from 'server/utils/errors'; import { getInitialData } from 'server/utils/initData'; import { generateMetaComponents, renderToNodeStream } from 'server/utils/ssr'; import { @@ -43,6 +50,15 @@ const parseSpamFieldFilterParam = ( }; const getTabProps = async (tabKind: SuperAdminTabKind, locationData: types.LocationData) => { + if (tabKind === 'customDomains') { + const communities = await Community.findAll({ + where: { domain: { [Op.ne]: null } }, + attributes: ['id', 'subdomain', 'domain', 'title'], + order: [['domain', 'ASC']], + raw: true, + }); + return { communities, cloudflareConfigured: isCloudflareConfigured() }; + } if (tabKind === 'exploreCommunities') { return { communities: await getExploreCommunities() }; } @@ -125,6 +141,89 @@ router.get('/superadmin', async (_, res) => { return res.redirect(getSuperAdminTabUrl(firstTab)); }); +// ── Custom Domains API ────────────────────────────────────────────────────── + +router.post('/api/superadmin/custom-domains', async (req, res, next) => { + try { + const initialData = await getInitialData(req); + if (!initialData.loginData.isSuperAdmin) { + throw new ForbiddenError(); + } + const { communityId, domain } = req.body; + if (!communityId || !domain) { + throw new BadRequestError(new Error('communityId and domain are required')); + } + + const hostname = String(domain).toLowerCase().trim(); + if (!/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/.test(hostname)) { + throw new BadRequestError(new Error('Invalid domain format')); + } + + const identifier = String(communityId).trim(); + // Support both UUID and subdomain + const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test( + identifier, + ); + const community = isUuid + ? await Community.findByPk(identifier) + : await Community.findOne({ where: { subdomain: identifier } }); + if (!community) { + throw new NotFoundError(new Error('Community not found')); + } + + // Check if domain is already in use + const existing = await Community.findOne({ where: { domain: hostname } }); + if (existing && existing.id !== community.id) { + throw new BadRequestError(new Error('Domain is already in use by another community')); + } + + // Add to Cloudflare first + await addCustomHostname(hostname); + + // Update the community + await community.update({ domain: hostname }); + + return res.json({ + id: community.id, + subdomain: community.subdomain, + domain: hostname, + title: community.title, + }); + } catch (err) { + return handleErrors(req, res, next)(err); + } +}); + +router.delete('/api/superadmin/custom-domains', async (req, res, next) => { + try { + const initialData = await getInitialData(req); + if (!initialData.loginData.isSuperAdmin) { + throw new ForbiddenError(); + } + const { communityId } = req.body; + if (!communityId) { + throw new BadRequestError(new Error('communityId is required')); + } + + const community = await Community.findByPk(communityId); + if (!community) { + throw new NotFoundError(new Error('Community not found')); + } + + if (community.domain) { + // Remove from Cloudflare first + await removeCustomHostname(community.domain); + } + + // Clear the domain + await community.update({ domain: null }); + + return res.json({ success: true }); + } catch (err) { + return handleErrors(req, res, next)(err); + } +}); + router.get('/superadmin/:tabKind', async (req, res, next) => { try { const { tabKind } = req.params; diff --git a/server/utils/cloudflareCustomHostnames.ts b/server/utils/cloudflareCustomHostnames.ts new file mode 100644 index 000000000..d7a312a74 --- /dev/null +++ b/server/utils/cloudflareCustomHostnames.ts @@ -0,0 +1,75 @@ +/** + * Cloudflare Custom Hostnames API client. + * + * Manages custom hostnames for community custom domains via the Cloudflare + * SSL for SaaS (Custom Hostnames) API. + * + * Required env vars: + * CLOUDFLARE_CUSTOM_HOSTNAME_API_TOKEN – API token with SSL & Hostnames:Edit + * CLOUDFLARE_ZONE_TAG – Zone ID (shared with analytics) + */ + +import { env } from 'server/env'; + +const CF_API_BASE = 'https://api.cloudflare.com/client/v4'; + +function getConfig() { + const apiToken = env.CLOUDFLARE_CUSTOM_HOSTNAME_API_TOKEN; + const zoneId = env.CLOUDFLARE_ZONE_TAG; + if (!apiToken || !zoneId) { + return null; + } + return { apiToken, zoneId }; +} + +async function cfFetch(path: string, options: RequestInit = {}) { + const config = getConfig(); + if (!config) { + throw new Error( + 'Cloudflare custom hostnames not configured. Set CLOUDFLARE_CUSTOM_HOSTNAME_API_TOKEN and CLOUDFLARE_ZONE_TAG.', + ); + } + const url = `${CF_API_BASE}/zones/${config.zoneId}${path}`; + const res = await fetch(url, { + ...options, + headers: { + Authorization: `Bearer ${config.apiToken}`, + 'Content-Type': 'application/json', + ...((options.headers as Record) ?? {}), + }, + }); + const json = await res.json(); + if (!json.success) { + const msgs = (json.errors ?? []).map((e: any) => e.message).join('; '); + throw new Error(`Cloudflare API error: ${msgs || res.statusText}`); + } + return json; +} + +export async function addCustomHostname(hostname: string) { + return cfFetch('/custom_hostnames', { + method: 'POST', + body: JSON.stringify({ + hostname, + ssl: { + method: 'http', + type: 'dv', + }, + }), + }); +} + +export async function removeCustomHostname(hostname: string) { + // First find the custom hostname ID by listing and filtering + const listRes = await cfFetch(`/custom_hostnames?hostname=${encodeURIComponent(hostname)}`); + const entry = (listRes.result ?? []).find((r: any) => r.hostname === hostname); + if (!entry) { + // Already removed or never existed — treat as success + return { success: true }; + } + return cfFetch(`/custom_hostnames/${entry.id}`, { method: 'DELETE' }); +} + +export function isCloudflareConfigured() { + return getConfig() !== null; +} diff --git a/utils/superAdmin.ts b/utils/superAdmin.ts index 1cd72f9a0..ec00954cf 100644 --- a/utils/superAdmin.ts +++ b/utils/superAdmin.ts @@ -1,5 +1,6 @@ export const superAdminTabKinds = [ 'analytics', + 'customDomains', 'exploreCommunities', 'landingPageFeatures', 'spam',