1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 window.SessionDB = function() {
8 loadFromLocalStorage: function() {
10 return JSON.parse(window.localStorage.getItem('sessions')) || {}
15 var all = db.loadFromLocalStorage()
16 if (window.defaultSession) {
17 window.defaultSession.isFromRails = true
18 all[window.defaultSession.user.uuid.slice(0, 5)] = window.defaultSession
22 loadActive: function() {
23 var sessions = db.loadAll()
24 Object.keys(sessions).forEach(function(key) {
25 if (!sessions[key].token)
30 save: function(k, v) {
31 var sessions = db.loadAll()
33 Object.keys(sessions).forEach(function(key) {
34 if (sessions[key].isFromRails)
37 window.localStorage.setItem('sessions', JSON.stringify(sessions))
40 var sessions = db.loadAll()
42 window.localStorage.setItem('sessions', JSON.stringify(sessions))
44 findAPI: function(url) {
45 // Given a Workbench or API host or URL, return a promise
46 // for the corresponding API server's base URL. Typical
48 // sessionDB.findAPI('https://workbench.example/foo').then(sessionDB.login)
49 if (url.indexOf('://') < 0)
50 url = 'https://' + url
52 return m.request(url.origin + '/discovery/v1/apis/arvados/v1/rest').then(function() {
53 return url.origin + '/'
54 }).catch(function(err) {
55 // If url is a Workbench site (and isn't too old),
56 // /status.json will tell us its API host.
57 return m.request(url.origin + '/status.json').then(function(resp) {
59 throw 'no apiBaseURL in status response'
60 return resp.apiBaseURL
64 login: function(baseURL) {
65 // Initiate login procedure with given API base URL (e.g.,
66 // "http://api.example/").
68 // Any page that has a button that invokes login() must
69 // also call checkForNewToken() on (at least) its first
70 // render. Otherwise, the login procedure can't be
72 document.location = baseURL + 'login?return_to=' + encodeURIComponent(document.location.href.replace(/\?.*/, '')+'?baseURL='+encodeURIComponent(baseURL))
76 // Forget the token, but leave the other info in the db so
77 // the user can log in again without providing the login
79 var sessions = db.loadAll()
80 delete sessions[k].token
81 db.save(k, sessions[k])
83 checkForNewToken: function() {
84 // If there's a token and baseURL in the location bar (i.e.,
85 // we just landed here after a successful login), save it and
86 // scrub the location bar.
87 if (document.location.search[0] != '?')
90 document.location.search.slice(1).split('&').map(function(kv) {
91 var e = kv.indexOf('=')
94 params[decodeURIComponent(kv.slice(0, e))] = decodeURIComponent(kv.slice(e+1))
96 if (!params.baseURL || !params.api_token)
97 // Have a query string, but it's not a login callback.
99 params.token = params.api_token
100 delete params.api_token
101 db.save(params.baseURL, params)
102 history.replaceState({}, '', document.location.origin + document.location.pathname)
104 fillMissingUUIDs: function() {
105 var sessions = db.loadAll()
106 Object.keys(sessions).map(function(key) {
107 if (key.indexOf('://') < 0)
109 // key is the baseURL placeholder. We need to get our user
110 // record to find out the cluster's real uuid prefix.
111 var session = sessions[key]
112 m.request(session.baseURL+'arvados/v1/users/current', {
114 authorization: 'OAuth2 '+session.token,
116 }).then(function(user) {
118 db.save(user.uuid.slice(0, 5), session)
123 request: function(session, path, opts) {
125 opts.headers = opts.headers || {}
126 opts.headers.authorization = 'OAuth2 '+ session.token
127 return m.request(session.baseURL + path, opts)