@braze/web-sdk
Version:
Braze SDK for web sites and other JS platforms.
387 lines (386 loc) • 13.7 kB
JavaScript
import { isArray as g, isEqual as ni } from "../util/code-utils.js";
import oi from "../models/push-token.js";
import { logger as E, EncodingUtils as ui } from "../../shared-lib/index.js";
import { STORAGE_KEYS as s } from "../managers/storage-manager.js";
import { User } from "../User/index.js";
import It from "./utils/push-utils.js";
import { getErrorMessage as ai } from "../util/error-utils.js";
export default class na {
constructor(i, t, e, s, r, n, o, u, a, h, c) {
(this.iu = i),
(this.tu = t),
(this.eu = e),
(this.su = r),
(this.ru = n),
(this.nu = o),
(this.h = u),
(this.ou = a),
(this.uu = h),
(this.C = c),
(this.iu = i),
(this.tu = t),
(this.eu = e),
(this.au = s + "/safari/" + t),
(this.su = r || "/service-worker.js"),
(this.nu = o),
(this.h = u),
(this.ou = a || !1),
(this.uu = h || !1),
(this.C = c),
(this.hu = It.cu()),
(this.fu = It.lu());
}
du() {
return this.uu;
}
pu(i, t, e, s, r) {
i.unsubscribe()
.then((i) => {
i
? this.bu(t, e, s, r)
: (E.error("Failed to unsubscribe device from push."),
"function" == typeof r && r(!1));
})
.catch((i) => {
E.error("Push unsubscription error: " + i),
"function" == typeof r && r(!1);
});
}
yu(i, t, e) {
var s;
const r = ((i) => {
if ("string" == typeof i) return i;
if (0 !== i.endpoint.indexOf("https://android.googleapis.com/gcm/send"))
return i.endpoint;
let t = i.endpoint;
const e = i;
return (
e.mu &&
-1 === i.endpoint.indexOf(e.mu) &&
(t = i.endpoint + "/" + e.mu),
t
);
})(i);
let n = null,
o = null;
const u = i;
if (null != u.getKey)
try {
const i = Array.from(new Uint8Array(u.getKey("p256dh"))),
t = Array.from(new Uint8Array(u.getKey("auth")));
(n = btoa(String.fromCharCode.apply(null, i))),
(o = btoa(String.fromCharCode.apply(null, t)));
} catch (i) {
E.error(ai(i));
}
const a = ((i) => {
let t;
return i.options &&
(t = i.options.applicationServerKey) &&
t.byteLength &&
t.byteLength > 0
? btoa(String.fromCharCode.apply(null, Array.from(new Uint8Array(t))))
.replace(/\+/g, "-")
.replace(/\//g, "_")
: null;
})(u);
null === (s = this.iu) || void 0 === s || s.gu(r, t, n, o, a),
r && "function" == typeof e && e(r, n, o);
}
vu() {
var i;
null === (i = this.iu) || void 0 === i || i.wu(!0);
}
ku(i, t) {
var e;
null === (e = this.iu) || void 0 === e || e.wu(!1),
E.info(i),
"function" == typeof t && t(!1);
}
Pu(i, t, e, s) {
var r;
if ("default" === t.permission)
try {
window.safari.pushNotification.requestPermission(
this.au,
i,
{
api_key: this.tu,
device_id:
(null === (r = this.eu) || void 0 === r ? void 0 : r.ve().id) ||
"",
},
(t) => {
"granted" === t.permission &&
this.iu &&
this.iu.setPushNotificationSubscriptionType(
User.NotificationSubscriptionTypes.OPTED_IN,
),
this.Pu(i, t, e, s);
},
);
} catch (i) {
this.ku("Could not request permission for push: " + i, s);
}
else
"denied" === t.permission
? this.ku(
"The user has blocked notifications from this site, or Safari push is not configured in the Braze dashboard.",
s,
)
: "granted" === t.permission &&
(E.info("Device successfully subscribed to push."),
this.yu(t.deviceToken, new Date(), e));
}
requestPermission(i, t, e) {
const s = (s) => {
switch (s) {
case "granted":
return void ("function" == typeof i && i());
case "default":
return void ("function" == typeof t && t());
case "denied":
return void ("function" == typeof e && e());
default:
E.error("Received unexpected permission result " + s);
}
};
let r = !1;
if ("default" !== window.Notification.permission)
s(Notification.permission);
else {
const i = window.Notification.requestPermission((i) => {
r && s(i);
});
i
? i.then((i) => {
s(i);
})
: (r = !0);
}
}
bu(i, t, e, s) {
const r = { userVisibleOnly: !0 };
null != t && (r.applicationServerKey = t),
i.pushManager
.subscribe(r)
.then((i) => {
E.info("Device successfully subscribed to push."),
this.yu(i, new Date(), e);
})
.catch((i) => {
It.isPushBlocked()
? (E.info("Permission for push notifications was denied."),
"function" == typeof s && s(!1))
: (E.error("Push subscription failed: " + i),
"function" == typeof s && s(!0));
});
}
Du() {
if (this.ou) return navigator.serviceWorker.getRegistration(this.su);
const i = this.ru ? { scope: this.ru } : void 0;
return navigator.serviceWorker.register(this.su, i).then(() =>
navigator.serviceWorker.ready.then(
(i) => (
i &&
"function" == typeof i.update &&
i.update().catch((i) => {
E.info("ServiceWorker update failed: " + i);
}),
i
),
),
);
}
Su(i) {
this.ou ||
(i.unregister(), E.info("Service worker successfully unregistered."));
}
subscribe(i, t) {
if (!It.isPushSupported())
return E.info(na.Au), void ("function" == typeof t && t(!1));
if (this.hu) {
if (!this.ou && null != window.location) {
let i = this.su;
-1 === i.indexOf(window.location.host) &&
(i = window.location.host + i),
-1 === i.indexOf(window.location.protocol) &&
(i = window.location.protocol + "//" + i);
}
if (It.isPushBlocked())
return void this.ku(
"Notifications from this site are blocked. This may be a temporary embargo or a permanent denial.",
t,
);
if (this.h && !this.h.ju() && 0 === this.h.Ot())
return (
E.info(
"Waiting for VAPID key from server config before subscribing to push.",
),
void this.h.xu(() => {
this.subscribe(i, t);
})
);
const e = () => {
E.info("Permission for push notifications was denied."),
"function" == typeof t && t(!1);
},
r = () => {
let i = "Permission for push notifications was ignored.";
It.isPushBlocked() &&
(i +=
" The browser has automatically blocked further permission requests for a period (probably 1 week)."),
E.info(i),
"function" == typeof t && t(!0);
},
n = It.isPushPermissionGranted(),
o = () => {
!n &&
this.iu &&
this.iu.setPushNotificationSubscriptionType(
User.NotificationSubscriptionTypes.OPTED_IN,
),
this.Du()
.then((e) => {
if (null == e)
return (
E.error(
"No service worker registration. Set the `manageServiceWorkerExternally` initialization option to false or ensure that your service worker is registered before calling registerPush.",
),
void ("function" == typeof t && t(!0))
);
e.pushManager
.getSubscription()
.then((r) => {
var n;
let o = null;
if (
(null !=
(null === (n = this.h) || void 0 === n
? void 0
: n.ju()) && (o = ui.Nu(this.h.ju())),
r)
) {
let n,
u = null,
a = null;
if ((this.C && (n = this.C.Rt(s.Tt.Uu)), n && !g(n))) {
let i;
try {
i = oi._u(n).Wu;
} catch (t) {
i = null;
}
null == i ||
isNaN(i.getTime()) ||
0 === i.getTime() ||
((u = i),
(a = new Date(u)),
a.setMonth(u.getMonth() + 6));
}
null != o &&
r.options &&
r.options.applicationServerKey &&
r.options.applicationServerKey.byteLength &&
r.options.applicationServerKey.byteLength > 0 &&
!ni(o, new Uint8Array(r.options.applicationServerKey))
? (r.options.applicationServerKey.byteLength > 12
? E.info(
"Device was already subscribed to push using a different VAPID provider, creating new subscription.",
)
: E.info(
"Attempting to upgrade a gcm_sender_id-based push registration to VAPID - depending on the browser this may or may not result in the same gcm_sender_id-based subscription.",
),
this.pu(r, e, o, i, t))
: r.expirationTime &&
new Date(r.expirationTime).valueOf() <=
new Date().valueOf()
? (E.info(
"Push subscription is expired, creating new subscription.",
),
this.pu(r, e, o, i, t))
: n && g(n)
? this.pu(r, e, o, i, t)
: null == a
? (E.info(
"No push subscription creation date found, creating new subscription.",
),
this.pu(r, e, o, i, t))
: a.valueOf() <= new Date().valueOf()
? (E.info(
"Push subscription older than 6 months, creating new subscription.",
),
this.pu(r, e, o, i, t))
: (E.info(
"Device already subscribed to push, sending existing subscription to backend.",
),
this.yu(r, u, i));
} else this.bu(e, o, i, t);
})
.catch((i) => {
E.error("Error checking current push subscriptions: " + i);
});
})
.catch((i) => {
E.error("ServiceWorker registration failed: " + i);
});
};
this.requestPermission(o, r, e);
} else if (this.fu) {
if (null == this.nu || "" === this.nu)
return (
E.error(
"You must supply the safariWebsitePushId initialization option in order to use registerPush on Safari",
),
void ("function" == typeof t && t(!0))
);
const e = window.safari.pushNotification.permission(this.nu);
this.Pu(this.nu, e, i, t);
}
}
unsubscribe(i, t) {
if (!It.isPushSupported())
return E.info(na.Au), void ("function" == typeof t && t());
this.hu
? navigator.serviceWorker.getRegistration(this.su).then((e) => {
e
? e.pushManager
.getSubscription()
.then((s) => {
s
? (this.vu(),
s
.unsubscribe()
.then((s) => {
s
? (E.info(
"Device successfully unsubscribed from push.",
),
"function" == typeof i && i())
: (E.error(
"Failed to unsubscribe device from push.",
),
"function" == typeof t && t()),
this.Su(e);
})
.catch((i) => {
E.error("Push unsubscription error: " + i),
"function" == typeof t && t();
}))
: (E.info("Device already unsubscribed from push."),
"function" == typeof i && i());
})
.catch((i) => {
E.error("Error unsubscribing from push: " + i),
"function" == typeof t && t();
})
: (E.info("Device already unsubscribed from push."),
"function" == typeof i && i());
})
: this.fu &&
(this.vu(),
E.info("Device unsubscribed from push."),
"function" == typeof i && i());
}
}
na.Au = "Push notifications are not supported in this browser.";