PageSourceSearch

https://id.priyadi.net/assets/controllers/push-device_controller-2svt9Ii.js

js priyadi.net collected 2026-10-02 06:18:32 UTC 32,049 bytes, 779 lines download raw bytes

vendor: 4,072 bytes, lines 1-119
1function _assert_this_initialized(self) {
2    if (self === void 0) {
3        throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
4    }
5    return self;
6}
7function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
8    try {
9        var info = gen[key](arg);
10        var value = info.value;
11    } catch (error) {
12        reject(error);
13        return;
14    }
15    if (info.done) {
16        resolve(value);
17    } else {
18        Promise.resolve(value).then(_next, _throw);
19    }
20}
21function _async_to_generator(fn) {
22    return function() {
23        var self = this, args = arguments;
24        return new Promise(function(resolve, reject) {
25            var gen = fn.apply(self, args);
26            function _next(value) {
27                asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
28            }
29            function _throw(err) {
30                asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
31            }
32            _next(undefined);
33        });
34    };
35}
36function _class_call_check(instance, Constructor) {
37    if (!(instance instanceof Constructor)) {
38        throw new TypeError("Cannot call a class as a function");
39    }
40}
41function _defineProperties(target, props) {
42    for(var i = 0; i < props.length; i++){
43        var descriptor = props[i];
44        descriptor.enumerable = descriptor.enumerable || false;
45        descriptor.configurable = true;
46        if ("value" in descriptor) descriptor.writable = true;
47        Object.defineProperty(target, descriptor.key, descriptor);
48    }
49}
50function _create_class(Constructor, protoProps, staticProps) {
51    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
52    if (staticProps) _defineProperties(Constructor, staticProps);
53    return Constructor;
54}
55function _define_property(obj, key, value) {
56    if (key in obj) {
57        Object.defineProperty(obj, key, {
58            value: value,
59            enumerable: true,
60            configurable: true,
61            writable: true
62        });
63    } else {
64        obj[key] = value;
65    }
66    return obj;
67}
68function _get_prototype_of(o) {
69    _get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
70        return o.__proto__ || Object.getPrototypeOf(o);
71    };
72    return _get_prototype_of(o);
73}
74function _inherits(subClass, superClass) {
75    if (typeof superClass !== "function" && superClass !== null) {
76        throw new TypeError("Super expression must either be null or a function");
77    }
78    subClass.prototype = Object.create(superClass && superClass.prototype, {
79        constructor: {
80            value: subClass,
81            writable: true,
82            configurable: true
83        }
84    });
85    if (superClass) _set_prototype_of(subClass, superClass);
86}
87function _object_spread(target) {
88    for(var i = 1; i < arguments.length; i++){
89        var source = arguments[i] != null ? arguments[i] : {};
90        var ownKeys = Object.keys(source);
91        if (typeof Object.getOwnPropertySymbols === "function") {
92            ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
93                return Object.getOwnPropertyDescriptor(source, sym).enumerable;
94            }));
95        }
96        ownKeys.forEach(function(key) {
97            _define_property(target, key, source[key]);
98        });
99    }
100    return target;
101}
102function ownKeys(object, enumerableOnly) {
103    var keys = Object.keys(object);
104    if (Object.getOwnPropertySymbols) {
105        var symbols = Object.getOwnPropertySymbols(object);
106        if (enumerableOnly) {
107            symbols = symbols.filter(function(sym) {
108                return Object.getOwnPropertyDescriptor(object, sym).enumerable;
109            });
110        }
111        keys.push.apply(keys, symbols);
112    }
113    return keys;
114}
115function _object_spread_props(target, source) {
116    source = source != null ? source : {};
117    if (Object.getOwnPropertyDescriptors) {
118        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
119    } else {
120        ownKeys(Object(source)).forEach(function(key) {
121            Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
122        });
123    }
124    return target;
125}
126function _possible_constructor_return(self, call) {
127    if (call && (_type_of(call) === "object" || typeof call === "function")) {
128        return call;
129    }
130    return _assert_this_initialized(self);
131}
132function _set_prototype_of(o, p) {
133    _set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o, p) {
134        o.__proto__ = p;
135        return o;
136    };
137    return _set_prototype_of(o, p);
138}
139function _type_of(obj) {
140    "@swc/helpers - typeof";
141    return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
142}
143function _is_native_reflect_construct() {
144    if (typeof Reflect === "undefined" || !Reflect.construct) return false;
145    if (Reflect.construct.sham) return false;
146    if (typeof Proxy === "function") return true;
147    try {
148        Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
149        return true;
150    } catch (e) {
151        return false;
152    }
153}
154function _create_super(Derived) {
155    var hasNativeReflectConstruct = _is_native_reflect_construct();
156    return function _createSuperInternal() {
157        var Super = _get_prototype_of(Derived), result;
158        if (hasNativeReflectConstruct) {
159            var NewTarget = _get_prototype_of(this).constructor;
160            result = Reflect.construct(Super, arguments, NewTarget);
161        } else {
162            result = Super.apply(this, arguments);
163        }
164        return _possible_constructor_return(this, result);
165    };
166}
167function _ts_generator(thisArg, body) {
168    var f, y, t, g, _ = {
169        label: 0,
170        sent: function() {
171            if (t[0] & 1) throw t[1];
172            return t[1];
173        },
174        trys: [],
175        ops: []
176    };
177    return g = {
178        next: verb(0),
179        "throw": verb(1),
180        "return": verb(2)
181    }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
182        return this;
183    }), g;
184    function verb(n) {
185        return function(v) {
186            return step([
187                n,
188                v
189            ]);
190        };
191    }
192    function step(op) {
193        if (f) throw new TypeError("Generator is already executing.");
194        while(_)try {
195            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
196            if (y = 0, t) op = [
197                op[0] & 2,
198                t.value
199            ];
200            switch(op[0]){
201                case 0:
202                case 1:
203                    t = op;
204                    break;
205                case 4:
206                    _.label++;
207                    return {
208                        value: op[1],
209                        done: false
210                    };
211                case 5:
212                    _.label++;
213                    y = op[1];
214                    op = [
215                        0
216                    ];
217                    continue;
218                case 7:
219                    op = _.ops.pop();
220                    _.trys.pop();
221                    continue;
222                default:
223                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
224                        _ = 0;
225                        continue;
226                    }
227                    if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
228                        _.label = op[1];
229                        break;
230                    }
231                    if (op[0] === 6 && _.label < t[1]) {
232                        _.label = t[1];
233                        t = op;
234                        break;
235                    }
236                    if (t && _.label < t[2]) {
237                        _.label = t[2];
238                        _.ops.push(op);
239                        break;
240                    }
241                    if (t[2]) _.ops.pop();
242                    _.trys.pop();
243                    continue;
244            }
245            op = body.call(thisArg, _);
246        } catch (e) {
247            op = [
248                6,
249                e
250            ];
251            y = 0;
252        } finally{
253            f = t = 0;
254        }
255        if (op[0] & 5) throw op[1];
256        return {
257            value: op[0] ? op[1] : void 0,
258            done: true
259        };
260    }
261}
262import { Controller } from "@hotwired/stimulus";
263import { base64UrlToBytes, deleteRecords, detectSupport, forgetDevice, generateDeviceKey, readDevice, readDevices, registerServiceWorker, reportSubscription, sign, subscribedWith, writeDevice } from "../lib/push-device.js";
264var _class = /*#__PURE__*/ function(Controller) {
265    "use strict";
266    _inherits(_class, Controller);
267    var _super = _create_super(_class);
268    function _class() {
269        _class_call_check(this, _class);
270        return _super.apply(this, arguments);
271    }
272    _create_class(_class, [
273        {
274            key: "connect",
275            value: function connect() {
276                var _this = this;
277                return _async_to_generator(function() {
278                    var support, record;
279                    return _ts_generator(this, function(_state) {
280                        switch(_state.label){
281                            case 0:
282                                support = detectSupport();
283                                _this.show(_this.hasUnsupportedTarget ? _this.unsupportedTarget : null, support === "unsupported");
284                                _this.show(_this.hasIosTarget ? _this.iosTarget : null, support === "ios-needs-home-screen");
285                                _this.show(_this.hasReadyTarget ? _this.readyTarget : null, support === "supported");
286                                if (!(_this.currentDeviceIdValue !== "" && _this.hasStaleTarget && support === "supported")) return [
287                                    3,
288                                    2
289                                ];
290                                return [
291                                    4,
292                                    readDevice(_this.currentDeviceIdValue).catch(function() {
293                                        return null;
294                                    })
295                                ];
296                            case 1:
297                                record = _state.sent();
298                                _this.show(_this.staleTarget, record === null);
299                                _state.label = 2;
300                            case 2:
301                                return [
302                                    2
303                                ];
304                        }
305                    });
306                })();
307            }
308        },
309        {
310            key: "register",
311            value: function register(event) {
312                var _this = this;
313                return _async_to_generator(function() {
314                    var options, subscription, json, keyPair, publicKey, signature, result, e;
315                    return _ts_generator(this, function(_state) {
316                        switch(_state.label){
317                            case 0:
318                                event.preventDefault();
319                                _this.setBusy(true);
320                                _this.setStatus("");
321                                _state.label = 1;
322                            case 1:
323                                _state.trys.push([
324                                    1,
325                                    12,
326                                    13,
327                                    14
328                                ]);
329                                return [
330                                    4,
331                                    _this.post(_this.optionsUrlValue, {})
332                                ];
333                            case 2:
334                                options = _state.sent();
335                                if (options.status === "reauth_required" && typeof options.redirect === "string") {
336                                    window.location.href = options.redirect;
337                                    return [
338                                        2
339                                    ];
340                                }
341                                if (options.status === "too_many_devices") {
342                                    _this.setStatus(_this.tooManyMessageValue);
343                                    return [
344                                        2
345                                    ];
346                                }
347                                if (options.status !== "ok" || typeof options.applicationServerKey !== "string" || typeof options.challenge !== "string") {
348                                    throw new Error("options");
349                                }
350                                return [
351                                    4,
352                                    Notification.requestPermission()
353                                ];
354                            case 3:
355                                if (_state.sent() !== "granted") {
356                                    _this.setStatus(_this.deniedMessageValue);
357                                    return [
358                                        2
359                                    ];
360                                }
361                                return [
362                                    4,
363                                    _this.sharedSubscription(options.applicationServerKey)
364                                ];
365                            case 4:
366                                subscription = _state.sent();
367                                json = subscription.toJSON();
368                                return [
369                                    4,
370                                    generateDeviceKey()
371                                ];
372                            case 5:
373                                keyPair = _state.sent();
374                                return [
375                                    4,
376                                    crypto.subtle.exportKey("jwk", keyPair.publicKey)
377                                ];
378                            case 6:
379                                publicKey = _state.sent();
380                                return [
381                                    4,
382                                    sign(keyPair.privateKey, "elpan-device-register\n" + options.challenge + "\n" + json.endpoint)
383                                ];
384                            case 7:
385                                signature = _state.sent();
386                                return [
387                                    4,
388                                    _this.post(_this.registerUrlValue, {
389                                        subscription: json,
390                                        publicKey: {
391                                            kty: publicKey.kty,
392                                            crv: publicKey.crv,
393                                            x: publicKey.x,
394                                            y: publicKey.y
395                                        },
396                                        signature: signature,
397                                        alerts: _this.hasAlertsTarget && _this.alertsTarget.checked,
398                                        approvals: _this.hasApprovalsTarget && _this.approvalsTarget.checked
399                                    })
400                                ];
401                            case 8:
402                                result = _state.sent();
403                                if (result.status === "reauth_required") {
404                                    window.location.reload();
405                                    return [
406                                        2
407                                    ];
408                                }
409                                if (result.status === "too_many_devices") {
410                                    _this.setStatus(_this.tooManyMessageValue);
411                                    return [
412                                        2
413                                    ];
414                                }
415                                if (result.status !== "ok" || typeof result.deviceId !== "string") {
416                                    throw new Error("register");
417                                }
418                                if (!(_this.currentDeviceIdValue !== "")) return [
419                                    3,
420                                    10
421                                ];
422                                return [
423                                    4,
424                                    deleteRecords([
425                                        _this.currentDeviceIdValue
426                                    ])
427                                ];
428                            case 9:
429                                _state.sent();
430                                _state.label = 10;
431                            case 10:
432                                return [
433                                    4,
434                                    writeDevice({
435                                        id: result.deviceId,
436                                        applicationServerKey: options.applicationServerKey,
437                                        privateKey: keyPair.privateKey
438                                    })
439                                ];
440                            case 11:
441                                _state.sent();
442                                window.location.reload();
443                                return [
444                                    3,
445                                    14
446                                ];
447                            case 12:
448                                e = _state.sent();
449                                _this.setStatus(_this.failedMessageValue);
450                                return [
451                                    3,
452                                    14
453                                ];
454                            case 13:
455                                _this.setBusy(false);
456                                return [
457                                    7
458                                ];
459                            case 14:
460                                return [
461                                    2
462                                ];
463                        }
464                    });
465                })();
466            }
467        },
468        {
469            key: "forget",
470            value: /**
471     * Before the form that removes THIS device is sent: drop the key and the
472     * subscription here too, so nothing is left behind that looks like a
473     * device.
474     */ function forget(event) {
475                var _this = this;
476                return _async_to_generator(function() {
477                    var form, e;
478                    return _ts_generator(this, function(_state) {
479                        switch(_state.label){
480                            case 0:
481                                form = event.currentTarget;
482                                if (form.dataset.forgotten === "1") {
483                                    return [
484                                        2
485                                    ];
486                                }
487                                event.preventDefault();
488                                _state.label = 1;
489                            case 1:
490                                _state.trys.push([
491                                    1,
492                                    3,
493                                    ,
494                                    4
495                                ]);
496                                return [
497                                    4,
498                                    forgetDevice(_this.currentDeviceIdValue)
499                                ];
500                            case 2:
501                                _state.sent();
502                                return [
503                                    3,
504                                    4
505                                ];
506                            case 3:
507                                e = _state.sent();
508                                return [
509                                    3,
510                                    4
511                                ];
512                            case 4:
513                                form.dataset.forgotten = "1";
514                                form.requestSubmit();
515                                return [
516                                    2
517                                ];
518                        }
519                    });
520                })();
521            }
522        },
523        {
524            key: "sharedSubscription",
525            value: /**
526     * The browser's one push subscription, shared by every account it is a
527     * device of. Kept when it was made with the server's key; otherwise made
528     * afresh — and then every other account's device on this browser is told
529     * the new one, signed with its own key, as the service worker does when
530     * the push service replaces it.
531     */ function sharedSubscription(applicationServerKey) {
532                var _this = this;
533                return _async_to_generator(function() {
534                    var registration, existing, subscription, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, record, status, err;
535                    return _ts_generator(this, function(_state) {
536                        switch(_state.label){
537                            case 0:
538                                return [
539                                    4,
540                                    registerServiceWorker()
541                                ];
542                            case 1:
543                                registration = _state.sent();
544                                return [
545                                    4,
546                                    registration.pushManager.getSubscription()
547                                ];
548                            case 2:
549                                existing = _state.sent();
550                                if (existing !== null && subscribedWith(existing, applicationServerKey)) {
551                                    return [
552                                        2,
553                                        existing
554                                    ];
555                                }
556                                return [
557                                    4,
558                                    existing === null || existing === void 0 ? void 0 : existing.unsubscribe()
559                                ];
560                            case 3:
561                                _state.sent();
562                                return [
563                                    4,
564                                    registration.pushManager.subscribe({
565                                        userVisibleOnly: true,
566                                        applicationServerKey: base64UrlToBytes(applicationServerKey)
567                                    })
568                                ];
569                            case 4:
570                                subscription = _state.sent();
571                                _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
572                                _state.label = 5;
573                            case 5:
574                                _state.trys.push([
575                                    5,
576                                    14,
577                                    15,
578                                    16
579                                ]);
580                                return [
581                                    4,
582                                    readDevices()
583                                ];
584                            case 6:
585                                _iterator = _state.sent()[Symbol.iterator]();
586                                _state.label = 7;
587                            case 7:
588                                if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
589                                    3,
590                                    13
591                                ];
592                                record = _step.value;
593                                if (record.id === _this.currentDeviceIdValue) {
594                                    return [
595                                        3,
596                         
596               12
597                                    ];
598                                }
599                                return [
600                                    4,
601                                    reportSubscription(record, subscription.toJSON())
602                                ];
603                            case 8:
604                                status = _state.sent();
605                                if (!(status === 404)) return [
606                                    3,
607                                    10
608                                ];
609                                return [
610                                    4,
611                                    deleteRecords([
612                                        record.id
613                                    ])
614                                ];
615                            case 9:
616                                _state.sent();
617                                return [
618                                    3,
619                                    12
620                                ];
621                            case 10:
622                                if (!(status === 200)) return [
623                                    3,
624                                    12
625                                ];
626                                return [
627                                    4,
628                                    writeDevice(_object_spread_props(_object_spread({}, record), {
629                                        applicationServerKey: applicationServerKey
630                                    }))
631                                ];
632                            case 11:
633                                _state.sent();
634                                _state.label = 12;
635                            case 12:
636                                _iteratorNormalCompletion = true;
637                                return [
638                                    3,
639                                    7
640                                ];
641                            case 13:
642                                return [
643                                    3,
644                                    16
645                                ];
646                            case 14:
647                                err = _state.sent();
648                                _didIteratorError = true;
649                                _iteratorError = err;
650                                return [
651                                    3,
652                                    16
653                                ];
654                            case 15:
655                                try {
656                                    if (!_iteratorNormalCompletion && _iterator.return != null) {
657                                        _iterator.return();
658                                    }
659                                } finally{
660                                    if (_didIteratorError) {
661                                        throw _iteratorError;
662                                    }
663                                }
664                                return [
665                                    7
666                                ];
667                            case 16:
668                                return [
669                                    2,
670                                    subscription
671                                ];
672                        }
673                    });
674                })();
675            }
676        },
677        {
678            key: "post",
679            value: function post(url, body) {
680                var _this = this;
681                return _async_to_generator(function() {
682                    var response;
683                    return _ts_generator(this, function(_state) {
684                        switch(_state.label){
685                            case 0:
686                                return [
687                                    4,
688                                    fetch(url, {
689                                        method: "POST",
690                                        credentials: "same-origin",
691                                        headers: {
692                                            "Content-Type": "application/json",
693                                            "X-CSRF-Token": _this.csrfTokenValue
694                                        },
695                                        body: JSON.stringify(body)
696                                    })
697                                ];
698                            case 1:
699                                response = _state.sent();
700                                return [
701                                    4,
702                                    response.json()
703                                ];
704                            case 2:
705                                return [
706                                    2,
707                                    _state.sent()
708                                ];
709                        }
710                    });
711                })();
712            }
713        },
714        {
715            key: "setBusy",
716            value: function setBusy(busy) {
717                if (this.hasButtonTarget) {
718                    this.buttonTarget.disabled = busy;
719                }
720            }
721        },
722        {
723            key: "setStatus",
724            value: function setStatus(message) {
725                if (!this.hasStatusTarget) {
726                    return;
727                }
728                this.statusTarget.textContent = message;
729                this.show(this.statusTarget, message !== "");
730            }
731        },
732        {
733            key: "show",
734            value: function show(element, visible) {
735                element === null || element === void 0 ? void 0 : element.classList.toggle("hidden", !visible);
736            }
737        }
738    ]);
739    return _class;
740}(Controller);
741_define_property(_class, "targets", [
742    "unsupported",
743    "ios",
744    "ready",
745    "button",
746    "status",
747    "stale",
748    "alerts",
749    "approvals"
750]);
751_define_property(_class, "values", {
752    optionsUrl: String,
753    registerUrl: String,
754    csrfToken: String,
755    currentDeviceId: String,
756    deniedMessage: String,
757    failedMessage: String,
758    tooManyMessage: String
759});
760/**
761 * The Devices page in the auth app: registers this browser as a Web Push
762 * device of the signed-in user, and forgets it again when the user removes
763 * it here.
764 *
765 * Registering, in order:
766 *
767 * 1. ask the server for the application server key and a challenge — which
768 *    answers "re-authenticate first" until the session has a fresh proof;
769 * 2. ask the user for notification permission (from the click: browsers
770 *    refuse or bury a prompt that no gesture started);
771 * 3. register the service worker and subscribe with that key — or keep the
772 *    subscription this browser already has as another account's device;
773 * 4. make a non-extractable ECDSA key, sign the challenge and the endpoint
774 *    with it, and send the subscription, the public key and the signature;
775 * 5. keep the device id and the private key in IndexedDB for the service
776 *    worker and the approval page.
777 *
778 * Every message is passed in pre-translated from the template.
779 */ export { _class as default };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.