Skip to content

Add S3 static publishing support for vanity URLs#35643

Open
riccardoruocco wants to merge 1 commit into
dotCMS:mainfrom
riccardoruocco:s3-static-push-manage-vanity-url
Open

Add S3 static publishing support for vanity URLs#35643
riccardoruocco wants to merge 1 commit into
dotCMS:mainfrom
riccardoruocco:s3-static-push-manage-vanity-url

Conversation

@riccardoruocco
Copy link
Copy Markdown
Contributor

Proposed Changes

  • Add a feature flag, STATIC_PUSH_S3_VANITY_ALIAS_ENABLED, to enable Vanity URL handling for AWS S3 static publishing. When the flag is false, dotCMS behaves exactly as it does today and no Vanity URL alias is generated.
  • When the flag is true, publishing a Vanity URL to a static S3 endpoint makes dotCMS resolve the target content, identify the live resource, render or copy it, and write the static clone to the S3 path represented by the Vanity URL.
  • This behavior is backed by the s3_vanity_alias table, which acts as an operational snapshot of the Vanity URL state on S3 and stores the aliases that have actually been materialized.
  • When a canonical content is republished, dotCMS checks the alias table and refreshes the existing Vanity URL clone if one is already tracked. If no Vanity URL alias exists yet, nothing changes.
  • When content is unpublished or removed, dotCMS uses the alias table to remove the corresponding static alias from S3 and keep the bucket aligned with the current state.
  • When a Vanity URL is unpublished or updated, dotCMS updates the tracked alias accordingly, so stale S3 keys are not left behind.

Additional Info

The goal of this change is to make Vanity URLs work on static S3 publishing in the same way they already work at runtime on live dotCMS.

The implementation is intentionally opt-in and does not affect existing installations unless STATIC_PUSH_S3_VANITY_ALIAS_ENABLED=true is set.

The s3_vanity_alias table is used as the source of truth for what was actually written to S3, so publish, republish, unpublish, and delete can all behave consistently without depending only on the current live content state.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0ef2efcf0c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +249 to +254
final List<S3VanityAlias> persistedAliases =
repository.findByVanityUrlId(context.endpointId, alias.vanityUrlId);
publishAlias(context, alias, file);
deleteObsoleteAliases(context, persistedAliases, alias);
repository.replaceMappingsByVanityUrlId(context.endpointId, alias.vanityUrlId,
Collections.singletonList(alias));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Scope vanity replacement to language

In multi-language Vanity URLs, the contentlet identifier is shared by language variants while this alias also stores languageId; looking up and then replacing solely by endpointId + vanityUrlId means publishing one translation loads/deletes every persisted alias for the same Vanity URL identifier on that endpoint. If the other language has a different vanity path, deleteObsoleteAliases removes its S3 object and replaceMappingsByVanityUrlId drops its row, so publishing one language can break aliases for the others. Include host/language (or the full lookup) in this operation.

Useful? React with 👍 / 👎.

Comment on lines +394 to +395
publishVanityAliasesForBundleAssetsIfEnabled(endPointPublisher, bucketRegion,
bucketPrefixProp, endpoint);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Refresh aliases when publishing canonical targets

This post-pass only handles Vanity URL contentlets from config.getAssets(), but when a bundle publishes the canonical page/file that existing Vanity URLs forward to, the vanity S3 clone is left untouched. The new S3VanityAliasService.publishAliases(S3VanityAliasContext) path that would refresh aliases by canonical path is not called anywhere, so users who update a page/file will keep serving stale content from its vanity key until they also republish the Vanity URL itself.

Useful? React with 👍 / 👎.

@semgrep-code-dotcms-test
Copy link
Copy Markdown
Contributor

Semgrep found 15 CUSTOM_INJECTION-2 findings:

The method identified is susceptible to injection. The input should be validated and properly
escaped.

If this is a critical or high severity finding, please also link this issue in the #security channel in Slack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant