{isWildcard && (
- Wildcard domains verify by ownership only; the alias is validated by Azure when the
- binding is created. Note: App Service Managed Certificates do not support wildcard
- domains — you will need to upload your own certificate for HTTPS.
+ Wildcard domains verify by ownership only; the alias is validated by Azure when
+ the binding is created. Note: App Service Managed Certificates do not support
+ wildcard domains — you will need to upload your own certificate for HTTPS.
)}
- {dnsResult && !ownershipVerified && (
+ {staleAsuid && (
+
+ A TXT record at {dnsResult?.AsuidHost} exists with an outdated
+ verification ID. Remove it (or update it to the value shown
+ above) — a stale domain-verification record blocks Azure's validation even when
+ the alias record is correct.
+
+ )}
+ {dnsResult && !staleAsuid && !canProceed && (
- The ownership TXT record hasn't propagated yet. DNS changes can take a few minutes.{" "}
+ {dnsResult.OwnershipRequired
+ ? "The required DNS records haven't propagated yet — DNS changes can take a few minutes. If your alias record is proxied (e.g. Cloudflare orange-cloud), Azure can't see it: either set it to DNS-only, or create the ownership TXT record shown above. "
+ : "The alias record hasn't propagated yet. DNS changes can take a few minutes. "}
{dnsResult.AliasDetail}
)}
- {dnsResult && ownershipVerified && !aliasVerified && !isWildcard && (
+ {dnsResult && canProceed && !aliasVerified && !isWildcard && (
- Ownership is verified. The alias record isn't visible yet — this is expected if the
- record is proxied (e.g. Cloudflare orange-cloud). You can continue; Azure will make
- the final check when the binding is created.
+ Ownership is verified. The alias record isn't visible yet — this is expected if
+ the record is proxied (e.g. Cloudflare orange-cloud). You can continue; Azure
+ will make the final check when the binding is created.
)}
{dnsCheck.isError && (
@@ -338,7 +385,8 @@ const DomainWizard = ({ open, onClose, siteInfo, initialDomain }) => {
{certDone ? (
}>
- {hostname} is fully configured and secured with a managed certificate.
+ {hostname} is fully configured and secured with a managed
+ certificate.
) : isWildcard ? (
@@ -348,8 +396,8 @@ const DomainWizard = ({ open, onClose, siteInfo, initialDomain }) => {
) : (
<>
- Provision a free App Service Managed Certificate for {hostname} and
- enable the SNI SSL binding. This can take a minute or two.
+ Provision a free App Service Managed Certificate for {hostname}{" "}
+ and enable the SNI SSL binding. This can take a minute or two.
If the domain's alias is proxied through a CDN (e.g. Cloudflare orange-cloud),
@@ -366,7 +414,10 @@ const DomainWizard = ({ open, onClose, siteInfo, initialDomain }) => {
{activeStep > 0 && !managing && (
-
- setActiveStep(1)}
- disabled={!ownershipVerified}
- >
+ setActiveStep(1)} disabled={!canProceed}>
Next
>
@@ -499,7 +546,11 @@ export const CippAppServiceDomains = () => {
- {row.Secured ? : }
+ {row.Secured ? (
+
+ ) : (
+
+ )}
{sslStateLabel(row.SslState)}
{row.HostNameType && (
@@ -533,11 +584,11 @@ export const CippAppServiceDomains = () => {
- Map custom domains to the App Service that hosts this CIPP instance. Each domain needs a DNS
- ownership record and an alias record, a hostname binding, and (optionally) a free managed
- TLS certificate — the wizard walks through all three and can be reopened at any time to
- finish or fix a domain. The default *.azurewebsites.net hostname always remains
- available.
+ Map custom domains to the App Service that hosts this CIPP instance. Each domain needs a
+ DNS ownership record and an alias record, a hostname binding, and (optionally) a free
+ managed TLS certificate — the wizard walks through all three and can be reopened at any
+ time to finish or fix a domain. The default *.azurewebsites.net hostname
+ always remains available.
@@ -565,8 +616,11 @@ export const CippAppServiceDomains = () => {
value={siteInfo?.CustomDomainVerificationId}
/>
- Use the default hostname as the CNAME target for subdomains, the inbound IP as the A
- record for apex domains, and the verification ID as the asuid TXT value.
+ Use the default hostname as the CNAME target for subdomains, and the inbound IP as
+ the A record for apex domains. The verification ID is only needed as an{" "}
+ asuid TXT value for apex, wildcard or proxied domains — a subdomain
+ CNAME verifies on its own, and a stale asuid record should be
+ removed.
)}
diff --git a/src/components/CippSettings/CippSSOSettings.jsx b/src/components/CippSettings/CippSSOSettings.jsx
index cc944882da8e..7a3055c1a533 100644
--- a/src/components/CippSettings/CippSSOSettings.jsx
+++ b/src/components/CippSettings/CippSSOSettings.jsx
@@ -84,6 +84,15 @@ export const CippSSOSettings = () => {
// (the original "Failed to create client secret after 5 attempts" bug).
const showCreate = !isProvisioned && !canRepair;
const isOrphanedError = statusKey === "error" && !hasAppId;
+ // Three states on purpose: warmup may not have attempted the grant yet, which is not the
+ // same as the tenant refusing it. Failure is a soft one — sign-in still works, users just
+ // see the consent prompt they see today.
+ const preconsentInfo =
+ data?.preconsented === true
+ ? { label: "Granted", color: "success" }
+ : data?.preconsented === false
+ ? { label: "Not Granted", color: "warning" }
+ : { label: "Not Checked", color: "default" };
const handleCreate = () => {
ssoAction.mutate({
@@ -204,6 +213,34 @@ export const CippSSOSettings = () => {
+ {hasAppId && (
+ <>
+
+
+ Admin Consent
+
+
+
+
+ {data?.preconsented === false && (
+
+ {data?.preconsentError
+ ? `Users will be prompted to consent at sign-in. ${data.preconsentError}`
+ : "Users will be prompted to consent at sign-in."}
+
+ )}
+
+ >
+ )}
+
{data?.appId && (
<>