RT26084: Hide Suspend button on suspended holds
[sitka/overdrive-evergreen-opac.git] / src / od_session.coffee
1 # We require the service of a session object to store essentials bits of
2 # information during a login session and between page reloads.  Here, we
3 # define a Session class implementing the service.
4
5 define [
6         'json'
7         'lodash'
8         'od_config'
9 ], (
10         json
11         _
12         config
13 ) ->
14
15         # A base class defining utilitarian methods
16         class U
17                 update: (x) ->
18                         return unless x
19                         t = @
20                         t extends x
21                         return
22                 store: ->
23                         json.stringify @, ( (n, v) -> if n is 'prototype' then undefined else v ), '  '
24                 retrieve: (x) ->
25                         x = if _.isString x
26                                 try
27                                         json.parse x
28                                 catch
29                                         undefined
30
31                 # The URL endpoint is converted to its reverse proxy version,
32                 # because we are using the Evergreen server as a reverse proxy to
33                 # the Overdrive server.
34                 proxy: (x) ->
35                         return unless x
36                         y = x
37                         y = y.replace 'https://', '//'
38                         y = y.replace 'http://' , '//'
39                         y = y.replace '//oauth-patron.overdrive.com', '/od/oauth-patron'
40                         y = y.replace        '//oauth.overdrive.com', '/od/oauth'
41                         y = y.replace   '//patron.api.overdrive.com', '/od/api-patron'
42                         y = y.replace          '//api.overdrive.com', '/od/api'
43                         y = y.replace  '//images.contentreserve.com', '/od/images'
44                         y = y.replace '//fulfill.contentreserve.com', '/od/fulfill'
45                         #log "proxy #{x} -> #{y}"
46                         y
47                 proxies: (x) ->
48                         (v.href = @proxy l) for n, v of x when l = v.href
49                         return x
50
51         class Prefs extends U
52                 @default:
53                         barcode: ''
54                         email_address: ''
55                         home_library: ''
56                 constructor: (x) -> @update x
57                 update: (x) -> super x or Prefs.default
58
59         class Creds extends U
60                 @default:
61                         username: ''
62                         password: 'xxxx'
63                 constructor: (x) -> @update x
64                 update: (x) -> super x or Creds.default
65
66                 # Calculate the effective username: either a barcode or a username (in the
67                 # hope that is a barcode) stored in session cache, or default to a null
68                 # string
69                 un: -> @barcode or @username
70
71                 # Calculate the effective password: either a password stored in session
72                 # cache or a dummy value
73                 pw: (required) -> if required then @password else 'xxxx'
74
75         # An essential role of the session object is to store the properties that
76         # are provided as a result of authenticating the client or the patron.
77         class Token extends U
78                 @default:
79                         access_token: undefined
80                         expires_in: undefined
81                         scope: undefined
82                         token_type: undefined
83
84                 constructor: (x) -> @update x
85                 update: (x) -> super x or Token.default
86                 # Is there a patron access token?  It is enough to test if the
87                 # parameters.scope text string mentions the word 'patron'.
88                 is_patron_access: -> /patron/i.test @scope
89
90         # Store the endpoints of the various APIs.  These include the endpoints for
91         # authenticating the client or the patron and the endpoints for getting
92         # library or patron information.  Upon authentication, other endpoints are
93         # dynamically accumulated within the object.
94         class Links extends U
95                 @default:
96                         token: href:              '//oauth.overdrive.com/token'
97                         libraries: href:            "//api.overdrive.com/v1/libraries/#{config.accountID}"
98                         patrontoken: href: '//oauth-patron.overdrive.com/patrontoken'
99                         patrons: href:       '//patron.api.overdrive.com/v1/patrons/me'
100                         holds: href: ''
101                         checkouts: href: ''
102                         products: ''
103                         advantageAccounts: ''
104                         search: ''
105                         availability: ''
106
107                 constructor: (x, logged_in) ->
108                         @update x
109                         @calibrate logged_in if x
110                         return
111                 update: (x) ->
112                         super @proxies Links.default unless x?
113                         super @proxies x.links if x?.links
114                         super @proxies x.linkTemplates if x?.linkTemplates
115                         return
116
117                 # Link templates should have empty values unless the current session is
118                 # logged in.
119                 calibrate: (logged_in) ->
120                         @search = @availability = '' unless logged_in
121                         return @
122
123         # Preserve the mapping between format id and format name that will be
124         # provided by the Library Account API.
125         class Labels extends U
126                 constructor: (x) -> @update x
127                 update: (x) -> super @to_object x.formats, 'id', 'name' if x?.formats
128                 # Return a new object from given an object that has a 'key' property and a
129                 # 'value' property
130                 to_object: (from, key, value) ->
131                         to = {}
132                         if from?.length > 0
133                                 to[x[key]] = x[value] for x in from
134                         return to
135
136         # Define a session object as a collection of sub-objects of the types just
137         # defined. Property values of any sub-object can be given in the argument.
138         # The argument can be a JSON string or an object.  If there are no property
139         # values given for a sub-object, intrinsic values will be used.
140         class Session extends U
141                 constructor: (x, logged_in) ->
142                         x = @retrieve x
143                         @prefs = new Prefs  x?.prefs
144                         @creds = new Creds  x?.creds
145                         @token = new Token  x?.token
146                         @links = new Links  x, logged_in
147                         @labels= new Labels x
148                         return
149
150         return Session