@braze/web-sdk
Version:
Braze SDK for web sites and other JS platforms.
387 lines (386 loc) • 13.7 kB
JavaScript
import { isArray as D, isEqual as ii } from "../util/code-utils.js";
import ti from "../models/push-token.js";
import { logger as E, EncodingUtils as ei } from "../../shared-lib/index.js";
import { STORAGE_KEYS as s } from "../managers/storage-manager.js";
import { User } from "../User/index.js";
import yt from "./utils/push-utils.js";
import { getErrorMessage as si } from "../util/error-utils.js";
export default class na {
constructor(i, t, e, s, r, n, o, u, a, h, c) {
(this.en = i),
(this.sn = t),
(this.on = e),
(this.un = r),
(this.an = n),
(this.hn = o),
(this.h = u),
(this.cn = a),
(this.fn = h),
(this.j = c),
(this.en = i),
(this.sn = t),
(this.on = e),
(this.ln = s + "/safari/" + t),
(this.un = r || "/service-worker.js"),
(this.hn = o),
(this.h = u),
(this.cn = a || !1),
(this.fn = h || !1),
(this.j = c),
(this.dn = yt.pn()),
(this.bn = yt.yn());
}
mn() {
return this.fn;
}
gn(i, t, e, s, r) {
i.unsubscribe()
.then((i) => {
i
? this.vn(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);
});
}
wn(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.kn &&
-1 === i.endpoint.indexOf(e.kn) &&
(t = i.endpoint + "/" + e.kn),
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(si(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.en) || void 0 === s || s.Pn(r, t, n, o, a),
r && "function" == typeof e && e(r, n, o);
}
Dn() {
var i;
null === (i = this.en) || void 0 === i || i.Sn(!0);
}
An(i, t) {
var e;
null === (e = this.en) || void 0 === e || e.Sn(!1),
E.info(i),
"function" == typeof t && t(!1);
}
jn(i, t, e, s) {
var r;
if ("default" === t.permission)
try {
window.safari.pushNotification.requestPermission(
this.ln,
i,
{
api_key: this.sn,
device_id:
(null === (r = this.on) || void 0 === r ? void 0 : r.fe().id) ||
"",
},
(t) => {
"granted" === t.permission &&
this.en &&
this.en.setPushNotificationSubscriptionType(
User.NotificationSubscriptionTypes.OPTED_IN,
),
this.jn(i, t, e, s);
},
);
} catch (i) {
this.An("Could not request permission for push: " + i, s);
}
else
"denied" === t.permission
? this.An(
"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.wn(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);
}
}
vn(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.wn(i, new Date(), e);
})
.catch((i) => {
yt.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));
});
}
xn() {
if (this.cn) return navigator.serviceWorker.getRegistration(this.un);
const i = this.an ? { scope: this.an } : void 0;
return navigator.serviceWorker.register(this.un, i).then(() =>
navigator.serviceWorker.ready.then(
(i) => (
i &&
"function" == typeof i.update &&
i.update().catch((i) => {
E.info("ServiceWorker update failed: " + i);
}),
i
),
),
);
}
Nn(i) {
this.cn ||
(i.unregister(), E.info("Service worker successfully unregistered."));
}
subscribe(i, t) {
if (!yt.isPushSupported())
return E.info(na.Un), void ("function" == typeof t && t(!1));
if (this.dn) {
if (!this.cn && null != window.location) {
let i = this.un;
-1 === i.indexOf(window.location.host) &&
(i = window.location.host + i),
-1 === i.indexOf(window.location.protocol) &&
(i = window.location.protocol + "//" + i);
}
if (yt.isPushBlocked())
return void this.An(
"Notifications from this site are blocked. This may be a temporary embargo or a permanent denial.",
t,
);
if (this.h && !this.h.Wn() && 0 === this.h.Ft())
return (
E.info(
"Waiting for VAPID key from server config before subscribing to push.",
),
void this.h._n(() => {
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.";
yt.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 = yt.isPushPermissionGranted(),
o = () => {
!n &&
this.en &&
this.en.setPushNotificationSubscriptionType(
User.NotificationSubscriptionTypes.OPTED_IN,
),
this.xn()
.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.Wn()) && (o = ei.Tn(this.h.Wn())),
r)
) {
let n,
u = null,
a = null;
if ((this.j && (n = this.j.lt(s.ct.In)), n && !D(n))) {
let i;
try {
i = ti.qn(n).Vn;
} 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 &&
!ii(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.gn(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.gn(r, e, o, i, t))
: n && D(n)
? this.gn(r, e, o, i, t)
: null == a
? (E.info(
"No push subscription creation date found, creating new subscription.",
),
this.gn(r, e, o, i, t))
: a.valueOf() <= new Date().valueOf()
? (E.info(
"Push subscription older than 6 months, creating new subscription.",
),
this.gn(r, e, o, i, t))
: (E.info(
"Device already subscribed to push, sending existing subscription to backend.",
),
this.wn(r, u, i));
} else this.vn(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.bn) {
if (null == this.hn || "" === this.hn)
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.hn);
this.jn(this.hn, e, i, t);
}
}
unsubscribe(i, t) {
if (!yt.isPushSupported())
return E.info(na.Un), void ("function" == typeof t && t());
this.dn
? navigator.serviceWorker.getRegistration(this.un).then((e) => {
e
? e.pushManager
.getSubscription()
.then((s) => {
s
? (this.Dn(),
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.Nn(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.bn &&
(this.Dn(),
E.info("Device unsubscribed from push."),
"function" == typeof i && i());
}
}
na.Un = "Push notifications are not supported in this browser.";