"use strict";

function registerTicketAPI() {
  WinChan.onOpen(function (origin, args, cb) {
    // NOTE: origin is a trusted value we get from the browser. args
    // is untrusted data from some other origin. It is absolutely
    // critical that we do not eval anything in there, including as
    // HTML. If attaching it to DOM, only use textContent and
    // equivalent APIs.

    // FIXME: ui.js should probably provide some sane API. Maybe a
    // logged in callback? I dunno. Really the UI flow should probably
    // be controlled by the page with ui.js or something similar just
    // providing the functions to actually create these things? I
    // dunno. This currently has silliness where, if onOpen gets
    // called after the UI is shown, placeholder values are visible.

    // TODO: Sanitize this request some more?
    if (!args.realm || !args.principal) {
        cb({
            status: "ERROR",
            code: "BAD_REQUEST"
        });
        return;
    }

    function deny() {
        cb({
            status: "DENIED",
            code: "NOT_ALLOWED"
        });
    }

    // Require everyone to use SSL. (Is there no better way to do this
    // check.) We'll want to allow things like chrome-extension:// in
    // future probably, though chrome-extension://aslkdfjsdlkfjdslkfs
    // is not a useful string.
    if (origin.substring(0, 8) != "https://") {
        deny();
        return;
    }

    var principal = new krb.Principal({
        nameType: krb.KRB_NT_UNKNOWN,
        nameString: args.principal
    }, args.realm);

    getTGTSession().then(function(r) {
        var tgtSession = r[0], prompted = r[1];

        var authed = $('#request-ticket-template').children().clone();
        authed.appendTo(document.body);
        if (prompted)
            authed.fadeIn();

        authed.find('.client-principal').text(tgtSession.client.toString());
        authed.find('.foreign-origin').text(origin);
        authed.find('.service-principal').text(principal.toString());

        authed.find('.request-ticket-deny').click(deny);
        authed.find('.request-ticket-allow').click(function(e) {
            // None of these errors should really happen. Ideally this
            // file would be in control of the UI and this event
            // listener would only be hooked up when we've got a valid
            // tgtSession.
            if (!localStorage.getItem("tgtSession")) {
                log('No ticket');
                deny();
                return;
            }

            if (tgtSession.isExpired()) {
                // I guess this is actually possible if the ticket
                // expires while this user is deliberating.
                log('Ticket expired');
                deny();
                return;
            }

            // User gave us permission and we have a legit TGT. Let's go!
            KDC.getServiceSession(tgtSession, principal).then(
                function (session) {
                    // TODO: Do we want to store this in the ccache
                    // too, so a service which doesn't cache its own
                    // tickets needn't get new ones all the time?
                    // Also, the ccache needs some fancy abstraction
                    // or something.
                    cb({
                        status: 'OK',
                        session: session.toDict()
                    });
                },
                function (error) {
                    log(error);
                    deny();
                }).done();
        });
    }).done();
  });
}

@@ -1343,52 +1343,192 @@
 ing.
-%0A    if (origin.substring(0, 8) != %22https://
+ Also allow things running over%0A    // localhost. Overwise testing is a nightmare.%0A    if (origin.substring(0, 8) != %22https://%22 &&%0A        origin.substring(0, 17) != %22http://localhost:
 %22) %7B

Allow http://localhost:* also to request tickets