@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 N, 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.sn = i),
(this.on = t),
(this.un = e),
(this.an = r),
(this.hn = n),
(this.cn = o),
(this.B = u),
(this.fn = a),
(this.ln = h),
(this.C = c),
(this.sn = i),
(this.on = t),
(this.un = e),
(this.dn = s + "/safari/" + t),
(this.an = r || "/service-worker.js"),
(this.cn = o),
(this.B = u),
(this.fn = a || !1),
(this.ln = h || !1),
(this.C = c),
(this.pn = yt.bn()),
(this.yn = yt.mn());
}
gn() {
return this.ln;
}
vn(i, t, e, s, r) {
i.unsubscribe()
.then((i) => {
i
? this.wn(t, e, s, r)
: (N.error("Failed to unsubscribe device from push."),
"function" == typeof r && r(!1));
})
.catch((i) => {
N.error("Push unsubscription error: " + i),
"function" == typeof r && r(!1);
});
}
kn(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.Pn &&
-1 === i.endpoint.indexOf(e.Pn) &&
(t = i.endpoint + "/" + e.Pn),
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) {
N.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.sn) || void 0 === s || s.Dn(r, t, n, o, a),
r && "function" == typeof e && e(r, n, o);
}
Sn() {
var i;
null === (i = this.sn) || void 0 === i || i.An(!0);
}
jn(i, t) {
var e;
null === (e = this.sn) || void 0 === e || e.An(!1),
N.info(i),
"function" == typeof t && t(!1);
}
xn(i, t, e, s) {
var r;
if ("default" === t.permission)
try {
window.safari.pushNotification.requestPermission(
this.dn,
i,
{
api_key: this.on,
device_id:
(null === (r = this.un) || void 0 === r ? void 0 : r.ve().id) ||
"",
},
(t) => {
"granted" === t.permission &&
this.sn &&
this.sn.setPushNotificationSubscriptionType(
User.NotificationSubscriptionTypes.OPTED_IN,
),
this.xn(i, t, e, s);
},
);
} catch (i) {
this.jn("Could not request permission for push: " + i, s);
}
else
"denied" === t.permission
? this.jn(
"The user has blocked notifications from this site, or Safari push is not configured in the Braze dashboard.",
s,
)
: "granted" === t.permission &&
(N.info("Device successfully subscribed to push."),
this.kn(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:
N.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);
}
}
wn(i, t, e, s) {
const r = { userVisibleOnly: !0 };
null != t && (r.applicationServerKey = t),
i.pushManager
.subscribe(r)
.then((i) => {
N.info("Device successfully subscribed to push."),
this.kn(i, new Date(), e);
})
.catch((i) => {
yt.isPushBlocked()
? (N.info("Permission for push notifications was denied."),
"function" == typeof s && s(!1))
: (N.error("Push subscription failed: " + i),
"function" == typeof s && s(!0));
});
}
Nn() {
if (this.fn) return navigator.serviceWorker.getRegistration(this.an);
const i = this.hn ? { scope: this.hn } : void 0;
return navigator.serviceWorker.register(this.an, i).then(() =>
navigator.serviceWorker.ready.then(
(i) => (
i &&
"function" == typeof i.update &&
i.update().catch((i) => {
N.info("ServiceWorker update failed: " + i);
}),
i
),
),
);
}
Un(i) {
this.fn ||
(i.unregister(), N.info("Service worker successfully unregistered."));
}
subscribe(i, t) {
if (!yt.isPushSupported())
return N.info(na.Wn), void ("function" == typeof t && t(!1));
if (this.pn) {
if (!this.fn && null != window.location) {
let i = this.an;
-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.jn(
"Notifications from this site are blocked. This may be a temporary embargo or a permanent denial.",
t,
);
if (this.B && !this.B._n() && 0 === this.B.Et())
return (
N.info(
"Waiting for VAPID key from server config before subscribing to push.",
),
void this.B.Tn(() => {
this.subscribe(i, t);
})
);
const e = () => {
N.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)."),
N.info(i),
"function" == typeof t && t(!0);
},
n = yt.isPushPermissionGranted(),
o = () => {
!n &&
this.sn &&
this.sn.setPushNotificationSubscriptionType(
User.NotificationSubscriptionTypes.OPTED_IN,
),
this.Nn()
.then((e) => {
if (null == e)
return (
N.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.B) || void 0 === n
? void 0
: n._n()) && (o = ei.In(this.B._n())),
r)
) {
let n,
u = null,
a = null;
if ((this.C && (n = this.C.ft(s.gt.Vn)), n && !D(n))) {
let i;
try {
i = ti.zn(n).qn;
} 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
? N.info(
"Device was already subscribed to push using a different VAPID provider, creating new subscription.",
)
: N.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.vn(r, e, o, i, t))
: r.expirationTime &&
new Date(r.expirationTime).valueOf() <=
new Date().valueOf()
? (N.info(
"Push subscription is expired, creating new subscription.",
),
this.vn(r, e, o, i, t))
: n && D(n)
? this.vn(r, e, o, i, t)
: null == a
? (N.info(
"No push subscription creation date found, creating new subscription.",
),
this.vn(r, e, o, i, t))
: a.valueOf() <= new Date().valueOf()
? (N.info(
"Push subscription older than 6 months, creating new subscription.",
),
this.vn(r, e, o, i, t))
: (N.info(
"Device already subscribed to push, sending existing subscription to backend.",
),
this.kn(r, u, i));
} else this.wn(e, o, i, t);
})
.catch((i) => {
N.error("Error checking current push subscriptions: " + i);
});
})
.catch((i) => {
N.error("ServiceWorker registration failed: " + i);
});
};
this.requestPermission(o, r, e);
} else if (this.yn) {
if (null == this.cn || "" === this.cn)
return (
N.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.cn);
this.xn(this.cn, e, i, t);
}
}
unsubscribe(i, t) {
if (!yt.isPushSupported())
return N.info(na.Wn), void ("function" == typeof t && t());
this.pn
? navigator.serviceWorker.getRegistration(this.an).then((e) => {
e
? e.pushManager
.getSubscription()
.then((s) => {
s
? (this.Sn(),
s
.unsubscribe()
.then((s) => {
s
? (N.info(
"Device successfully unsubscribed from push.",
),
"function" == typeof i && i())
: (N.error(
"Failed to unsubscribe device from push.",
),
"function" == typeof t && t()),
this.Un(e);
})
.catch((i) => {
N.error("Push unsubscription error: " + i),
"function" == typeof t && t();
}))
: (N.info("Device already unsubscribed from push."),
"function" == typeof i && i());
})
.catch((i) => {
N.error("Error unsubscribing from push: " + i),
"function" == typeof t && t();
})
: (N.info("Device already unsubscribed from push."),
"function" == typeof i && i());
})
: this.yn &&
(this.Sn(),
N.info("Device unsubscribed from push."),
"function" == typeof i && i());
}
}
na.Wn = "Push notifications are not supported in this browser.";