feat(cloud): Add support for viewing status of SSL in custom domains (#12011)
# Pull Request Template ## Description Fixes [CW-4620](https://linear.app/chatwoot/issue/CW-4620/rethinking-custom-domains-in-chatwoot) <img width="642" height="187" alt="Screenshot 2025-07-29 at 8 17 44 PM" src="https://github.com/user-attachments/assets/ad2f5dac-4b27-4dce-93ca-6cbba74443fb" /> ## Type of change - [x] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com> Co-authored-by: Pranav <pranavrajs@gmail.com> Co-authored-by: Pranav <pranav@chatwoot.com>
This commit is contained in:
@@ -116,4 +116,24 @@ export const actions = {
|
||||
isSwitching,
|
||||
});
|
||||
},
|
||||
|
||||
sendCnameInstructions: async (_, { portalSlug, email }) => {
|
||||
try {
|
||||
await portalAPIs.sendCnameInstructions(portalSlug, email);
|
||||
} catch (error) {
|
||||
throwErrorMessage(error);
|
||||
}
|
||||
},
|
||||
|
||||
sslStatus: async ({ commit }, { portalSlug }) => {
|
||||
try {
|
||||
commit(types.SET_UI_FLAG, { isFetchingSSLStatus: true });
|
||||
const { data } = await portalAPIs.sslStatus(portalSlug);
|
||||
commit(types.SET_SSL_SETTINGS, { portalSlug, sslSettings: data });
|
||||
} catch (error) {
|
||||
throwErrorMessage(error);
|
||||
} finally {
|
||||
commit(types.SET_UI_FLAG, { isFetchingSSLStatus: false });
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ export const getters = {
|
||||
isFetchingPortals: state => state.uiFlags.isFetching,
|
||||
isCreatingPortal: state => state.uiFlags.isCreating,
|
||||
isSwitchingPortal: state => state.uiFlags.isSwitching,
|
||||
isFetchingSSLStatus: state => state.uiFlags.isFetchingSSLStatus,
|
||||
portalBySlug:
|
||||
(...getterArguments) =>
|
||||
portalId => {
|
||||
|
||||
@@ -6,6 +6,7 @@ export const defaultPortalFlags = {
|
||||
isFetching: false,
|
||||
isUpdating: false,
|
||||
isDeleting: false,
|
||||
isFetchingSSLStatus: false,
|
||||
};
|
||||
|
||||
const state = {
|
||||
|
||||
@@ -13,6 +13,7 @@ export const types = {
|
||||
REMOVE_PORTAL_ID: 'removePortalId',
|
||||
SET_HELP_PORTAL_UI_FLAG: 'setHelpCenterUIFlag',
|
||||
SET_PORTAL_SWITCHING_FLAG: 'setPortalSwitchingFlag',
|
||||
SET_SSL_SETTINGS: 'setSSLSettings',
|
||||
};
|
||||
|
||||
export const mutations = {
|
||||
@@ -110,4 +111,18 @@ export const mutations = {
|
||||
[types.SET_PORTAL_SWITCHING_FLAG]($state, { isSwitching }) {
|
||||
$state.uiFlags.isSwitching = isSwitching;
|
||||
},
|
||||
|
||||
[types.SET_SSL_SETTINGS]($state, { portalSlug, sslSettings }) {
|
||||
const portal = $state.portals.byId[portalSlug];
|
||||
$state.portals.byId = {
|
||||
...$state.portals.byId,
|
||||
[portalSlug]: {
|
||||
...portal,
|
||||
ssl_settings: {
|
||||
...portal.ssl_settings,
|
||||
...sslSettings,
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -135,6 +135,36 @@ describe('#actions', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#sslStatus', () => {
|
||||
it('commits SET_SSL_SETTINGS with data from API', async () => {
|
||||
axios.get.mockResolvedValue({
|
||||
data: { status: 'active', verification_errors: [] },
|
||||
});
|
||||
await actions.sslStatus({ commit }, { portalSlug: 'domain' });
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.SET_UI_FLAG, { isFetchingSSLStatus: true }],
|
||||
[
|
||||
types.SET_SSL_SETTINGS,
|
||||
{
|
||||
portalSlug: 'domain',
|
||||
sslSettings: { status: 'active', verification_errors: [] },
|
||||
},
|
||||
],
|
||||
[types.SET_UI_FLAG, { isFetchingSSLStatus: false }],
|
||||
]);
|
||||
});
|
||||
it('throws error and does not commit when API fails', async () => {
|
||||
axios.get.mockRejectedValue({ message: 'error' });
|
||||
await expect(
|
||||
actions.sslStatus({ commit }, { portalSlug: 'domain' })
|
||||
).rejects.toThrow(Error);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.SET_UI_FLAG, { isFetchingSSLStatus: true }],
|
||||
[types.SET_UI_FLAG, { isFetchingSSLStatus: false }],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#delete', () => {
|
||||
it('sends correct actions if API is success', async () => {
|
||||
axios.delete.mockResolvedValue({});
|
||||
|
||||
@@ -89,6 +89,25 @@ describe('#mutations', () => {
|
||||
isFetching: true,
|
||||
isUpdating: false,
|
||||
isDeleting: false,
|
||||
isFetchingSSLStatus: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('[types.SET_SSL_SETTINGS]', () => {
|
||||
it('merges new ssl settings into existing portal.ssl_settings', () => {
|
||||
state.portals.byId.domain = {
|
||||
slug: 'domain',
|
||||
ssl_settings: { cf_status: 'pending' },
|
||||
};
|
||||
mutations[types.SET_SSL_SETTINGS](state, {
|
||||
portalSlug: 'domain',
|
||||
sslSettings: { status: 'active', verification_errors: ['error'] },
|
||||
});
|
||||
expect(state.portals.byId.domain.ssl_settings).toEqual({
|
||||
cf_status: 'pending',
|
||||
status: 'active',
|
||||
verification_errors: ['error'],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user