<commit_before>// -------------------------------------------------------------------------- \\
// File: Auth.js                                                              \\
// Module: API                                                                \\
// Requires: SHA-256, namespace.js                                            \\
// Author: <NAME>                                                       \\
// License: © 2010-2015 FastMail Pty Ltd. MIT Licensed.                       \\
// -------------------------------------------------------------------------- \\

/*global O, JMAP, JSON, jsSHA */

"use strict";

( function ( JMAP ) {

var base64encode = function ( object ) {
    return btoa( JSON.stringify( object ) );
};

var b64tob64url = function ( string ) {
    return string
        .replace( /\=/g, '' )
        .replace( /\+/g, '-' )
        .replace( /\//g, '_' );
};

// ---

JMAP.auth = new O.Object({

    isAuthenticated: false,

    username: '',
    accessToken: '',
    signingId: '',
    signingKey: '',

    accounts: {},
    capabilities: {},

    authenticationUrl: '',
    apiUrl: '',
    downloadUrl: '',
    uploadUrl: '',
    eventSourceUrl: '',

    _isFetchingEndPoints: false,

    defaultAccountId: function () {
        var accounts = this.get( 'accounts' );
        var id;
        for ( id in accounts ) {
            if ( accounts[ id ].isPrimary ) {
                return id;
            }
        }
        return null;
    }.property( 'accounts' ),

    // ---

    signUrl: function ( url ) {
        var header = b64tob64url( base64encode({
            alg: 'HS256',
            typ: 'JWT'
        }));
        var payload = b64tob64url( base64encode({
            iss: this.get( 'signingId' ),
            sub: url.replace( /[?#].*/, '' ),
            iat: Math.floor( Date.now() / 1000 )
        }));
        var token = header + '.' + payload;
        var signingKey = this.get( 'signingKey' );
        var signature = signingKey ?
            '.' + b64tob64url(
                new jsSHA( 'SHA-256', 'TEXT' )
                    .setHMACKey( signingKey, 'B64' )
                    .update( token )
                    .getHMAC( 'B64' )
            ) :
            '';
        return url +
            ( url.contains( '?' ) ? '&' : '?' ) +
            'access_token=' + token + signature;
    },

    getUrlForBlob: function ( accountId, blobId, name ) {
        if ( !accountId ) {
            accountId = this.get( 'defaultAccountId' );
        }
        return this.signUrl(
            this.get( 'downloadUrl' )<commit_msg>Auth#signingKey is now in b64url format<commit_after>// -------------------------------------------------------------------------- \\
// File: Auth.js                                                              \\
// Module: API                                                                \\
// Requires: SHA-256, namespace.js                                            \\
// Author: <NAME>                                                       \\
// License: © 2010-2015 FastMail Pty Ltd. MIT Licensed.                       \\
// -------------------------------------------------------------------------- \\

/*global O, JMAP, JSON, jsSHA */

"use strict";

( function ( JMAP ) {

var base64encode = function ( object ) {
    return btoa( JSON.stringify( object ) );
};

var b64tob64url = function ( string ) {
    return string
        .replace( /\=/g, '' )
        .replace( /\+/g, '-' )
        .replace( /\//g, '_' );
};

var b64urltob64 = function ( string ) {
    return string
        .replace( /\-/g, '+' )
        .replace( /\_/g, '/' );
};

// ---

JMAP.auth = new O.Object({

    isAuthenticated: false,

    username: '',
    accessToken: '',
    signingId: '',
    signingKey: '',

    accounts: {},
    capabilities: {},

    authenticationUrl: '',
    apiUrl: '',
    downloadUrl: '',
    uploadUrl: '',
    eventSourceUrl: '',

    _isFetchingEndPoints: false,

    defaultAccountId: function () {
        var accounts = this.get( 'accounts' );
        var id;
        for ( id in accounts ) {
            if ( accounts[ id ].isPrimary ) {
                return id;
            }
        }
        return null;
    }.property( 'accounts' ),

    // ---

    signUrl: function ( url ) {
        var header = b64tob64url( base64encode({
            alg: 'HS256',
            typ: 'JWT'
        }));
        var payload = b64tob64url( base64encode({
            iss: this.get( 'signingId' ),
            sub: url.replace( /[?#].*/, '' ),
            iat: Math.floor( Date.now() / 1000 )
        }));
        var token = header + '.' + payload;
        var signingKey = this.get( 'signingKey' );
        var signature = signingKey ?
            '.' + b64tob64url(
                new jsSHA( 'SHA-256', 'TEXT' )
                    .setHMACKey( b64urltob64( signingKey ), 'B64' )
                    .update( token )
                    .getHMAC( 'B64' )
            ) :
            '';
        return url +
            ( url.contains( '?' ) ? '&' : '?' ) +
            'access_token=' + token + signature;
    },

    getUrlForBlob: function ( accountId, blobId, name ) {
        if ( !accountId ) {
            accountId = this.get( 'defaultAccountId' );
        }
        return this.signUrl(
            this.get( 'downloadUrl' )
{'fraction_non_alphanumeric': 0.1969640179910045, 'fraction_numerical': 0.019490254872563718, 'mean_word_length': 1.0686046511627907, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2926511', 'n_tokens_mistral': 1533, 'n_tokens_neox': 1443, 'n_words': 324}