summaryrefslogtreecommitdiffstats
path: root/packages/meteor-accounts-cas/cas_client.js
blob: ca9288ae2cb77efe88d603b66b3c1c8b0bfd54bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
function addParameterToURL(url, param){
  var urlSplit = url.split('?');
  return url+(urlSplit.length>0 ? '?':'&') + param;
}

Meteor.initCas = function(callback) {
    const casTokenMatch = window.location.href.match(/[?&]casToken=([^&]+)/);
    if (casTokenMatch == null) {
        return;
    }

    window.history.pushState('', document.title, window.location.href.replace(/([&?])casToken=[^&]+[&]?/, '$1').replace(/[?&]+$/g, ''));

    Accounts.callLoginMethod({
        methodArguments: [{ cas: { credentialToken: casTokenMatch[1] } }],
        userCallback: function(err){
            if (err == null) {
                // should we do anything on success?
            }
            if (callback != null) {
                callback(err);
            }
        }
    });
}

Meteor.loginWithCas = function(options, callback) {

    var credentialToken = Random.id();

    if (!Meteor.settings.public &&
        !Meteor.settings.public.cas &&
        !Meteor.settings.public.cas.loginUrl) {
        return;
    }

    var settings = Meteor.settings.public.cas;

    var backURL = window.location.href.replace('#', '');
    if (options != null && options.redirectUrl != null)
        backURL = options.redirectUrl;

    var serviceURL = addParameterToURL(backURL, 'casToken='+credentialToken);

    var loginUrl = settings.loginUrl +
        "?" + (settings.serviceParam || "service") + "=" +
        encodeURIComponent(serviceURL)

    if (settings.popup == false) {
      window.location = loginUrl;
      return;
    }

    var popup = openCenteredPopup(
        loginUrl,
        settings.width || 800,
        settings.height || 600
    );

    var checkPopupOpen = setInterval(function() {
        try {
	    if(popup && popup.document && popup.document.getElementById('popupCanBeClosed')) {
                popup.close();
      	    }
            // Fix for #328 - added a second test criteria (popup.closed === undefined)
            // to humour this Android quirk:
            // http://code.google.com/p/android/issues/detail?id=21061
            var popupClosed = popup.closed || popup.closed === undefined;
        } catch (e) {
            // For some unknown reason, IE9 (and others?) sometimes (when
            // the popup closes too quickly?) throws "SCRIPT16386: No such
            // interface supported" when trying to read 'popup.closed'. Try
            // again in 100ms.
            return;
        }

        if (popupClosed) {
            clearInterval(checkPopupOpen);

            // check auth on server.
            Accounts.callLoginMethod({
                methodArguments: [{ cas: { credentialToken: credentialToken } }],
                userCallback: err => {
                    // Fix redirect bug after login successfully
                    if (!err) {
                        window.location.href = '/';
                    }
                }
            });
        }
    }, 100);
};

var openCenteredPopup = function(url, width, height) {
  var screenX = typeof window.screenX !== 'undefined'
  ? window.screenX : window.screenLeft;
  var screenY = typeof window.screenY !== 'undefined'
  ? window.screenY : window.screenTop;
  var outerWidth = typeof window.outerWidth !== 'undefined'
  ? window.outerWidth : document.body.clientWidth;
  var outerHeight = typeof window.outerHeight !== 'undefined'
  ? window.outerHeight : (document.body.clientHeight - 22);
  // XXX what is the 22?

  // Use `outerWidth - width` and `outerHeight - height` for help in
  // positioning the popup centered relative to the current window
  var left = screenX + (outerWidth - width) / 2;
  var top = screenY + (outerHeight - height) / 2;
  var features = ('width=' + width + ',height=' + height +
      ',left=' + left + ',top=' + top + ',scrollbars=yes');

  var newwindow = window.open(url, '_blank', features);
  if (newwindow.focus)
    newwindow.focus();
  return newwindow;
};