diff --git a/css/interface.css b/css/interface.css
index 2c507d6..2d2ab12 100644
--- a/css/interface.css
+++ b/css/interface.css
@@ -549,3 +549,8 @@ h3 small {
align-items: center;
display: flex;
}
+
+#fl-push-testResultMessage {
+ padding: 10px 0;
+ display: none;
+}
\ No newline at end of file
diff --git a/interface.html b/interface.html
index 91607c0..bd841c8 100644
--- a/interface.html
+++ b/interface.html
@@ -1808,6 +1808,16 @@
+
diff --git a/js/apnValidation.js b/js/apnValidation.js
new file mode 100644
index 0000000..f8cf3d6
--- /dev/null
+++ b/js/apnValidation.js
@@ -0,0 +1,123 @@
+
+const authKeyInput = document.getElementById('fl-push-authKey');
+const keyIdInput = document.getElementById('fl-push-keyId');
+const teamIdInput = document.getElementById('fl-store-teams');
+const bundleIdInput = document.getElementById('fl-store-bundleId');
+
+const testConfigButton = document.getElementById('fl-push-testConfigButton');
+const testResultMessage = document.getElementById('fl-push-testResultMessage');
+
+const MESSAGE = {
+ SUCCESS: 'Success! Push notifications have been configured successfully.',
+ ERROR_INPUT: 'Error - notifications have not beeen configured, please check the details you have entered and try again',
+ ERROR_SERVER: 'Error - notifications have not been configured correctly. Please review https://help.fliplet.com or contact support.',
+ ERROR_NO_KEY: 'Authentication key is missing, please check provided information and try again',
+ ERROR_NO_KEYID: 'Key ID is missing, please check provided information and try again',
+ ERROR_NO_TEAMID: 'Developer team is missing, please check selected team in section: App Store > 5 - App technical details, and try again',
+ ERROR_NO_BUNDLEID: 'Bundle ID is missing, please check Bundle ID: App Store > 5 - App technical details, and try again',
+ ERROR_SERVICE: 'Error - There is currently an issue relating to APNs services. Please try again later.'
+};
+
+const mappedMessages = {
+ BadDeviceToken: MESSAGE.SUCCESS,
+ ExpiredProviderToken: MESSAGE.ERROR_INPUT,
+ InvalidProviderToken: MESSAGE.ERROR_INPUT,
+ TooManyRequests: MESSAGE.ERROR_SERVICE,
+ InternalServerError: MESSAGE.ERROR_SERVICE,
+ ServiceUnavailable: MESSAGE.ERROR_SERVICE,
+ Shutdown: MESSAGE.ERROR_SERVICE
+};
+
+const renderResultMessage = (resultMessage) => {
+ if (!resultMessage) {
+ testResultMessage.style.display = 'none';
+ testResultMessage.innerHTML = '';
+
+ return;
+ }
+
+ testResultMessage.style.display = 'block';
+ testResultMessage.innerHTML = resultMessage;
+
+ const success = resultMessage === MESSAGE.SUCCESS;
+
+ testResultMessage.classList.toggle('text-success', success);
+ testResultMessage.classList.toggle('text-danger', !success);
+};
+
+const validateApnKey = async({ apnAuthKey, apnKeyId, apnTeamId, apnTopic }) => {
+ const currentAppId = Fliplet.Env.get('appId');
+
+ try {
+ const response = await fetch(`/v1/apps/${currentAppId}/notifications/validate-apns-config`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({ apnAuthKey, apnKeyId, apnTeamId, apnTopic })
+ });
+
+ if (response.status === 200) {
+ const { 0: { message: { 0: { errorMsg } } } } = await (response.json());
+
+ const message = mappedMessages[errorMsg];
+
+ if (message) {
+ return message;
+ }
+ }
+
+ return MESSAGE.ERROR_SERVER;
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.error('Failed to send message:', error);
+
+ return MESSAGE.ERROR;
+ }
+};
+
+testConfigButton.addEventListener('click', async() => {
+ renderResultMessage(null);
+
+ let resultMessage = null;
+
+ const apnAuthKey = authKeyInput.value;
+ const apnKeyId = keyIdInput.value;
+ const apnTeamId = teamIdInput.value;
+ const apnTopic = bundleIdInput.value;
+
+
+ if (!apnAuthKey) {
+ resultMessage = MESSAGE.ERROR_NO_KEY;
+ } else if (!apnKeyId) {
+ resultMessage = MESSAGE.ERROR_NO_KEYID;
+ } else if (!apnTeamId) {
+ resultMessage = MESSAGE.ERROR_NO_TEAMID;
+ } else if (!apnTopic) {
+ resultMessage = MESSAGE.ERROR_NO_BUNDLEID;
+ } else {
+ resultMessage = await validateApnKey({ apnAuthKey, apnKeyId, apnTeamId, apnTopic });
+ }
+
+ renderResultMessage(resultMessage);
+});
+
+const clearMessage = () => {
+ renderResultMessage(null);
+};
+
+authKeyInput.addEventListener('input', clearMessage);
+keyIdInput.addEventListener('input', clearMessage);
+teamIdInput.addEventListener('input', clearMessage);
+
+function goToTechDetails() {
+ const appStoreTab = document.querySelector('[href="#appstore-tab"]');
+ const techDetailsDropdownAnchor = document.querySelector('[href="#appStoreTech"]');
+ const techDetailsDropdown = document.getElementById('appStoreTech');
+
+ appStoreTab.click();
+
+ if (techDetailsDropdown.getAttribute('aria-expanded') !== 'true') {
+ techDetailsDropdownAnchor.click();
+ }
+}
diff --git a/widget.json b/widget.json
index 79b96ad..37a42b2 100644
--- a/widget.json
+++ b/widget.json
@@ -29,7 +29,8 @@
"vendor/bootstrap-select.min.js",
"vendor/validator.js",
"css/interface.css",
- "js/interface.js"
+ "js/interface.js",
+ "js/apnValidation.js"
]
},
"build": {