9 |
--------------------------------------------------------------------------------
/src/main/webapp/media/js/notifications.js:
--------------------------------------------------------------------------------
1 | var socialFinanceNotifications = {
2 | notify : function(msg) {
3 | toastr.info(msg);
4 | },
5 |
6 | notifyError : function(msg) {
7 | toastr.error(msg);
8 | },
9 |
10 | notifyReload : function(msg, delay) {
11 | toastr.info(msg);
12 | if (!delay) var delay = 1500;
13 | setTimeout(function() {
14 | window.location.reload();
15 | }, delay);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 | *.db
3 | .DS_Store
4 | *.scala.orig
5 | *.orig
6 | *.log
7 | .gitignore
8 | .idea
9 | .settings
10 | .classpath
11 | .project
12 | .cache
13 | src/main/resources/rebel.xml
14 | src/main/resources/props/*
15 | !src/main/resources/props/sample.props.template
16 | src/test/resources/props
17 | src/main/resources/git.properties
18 |
19 | src/main/webapp/WEB-INF/jetty.xml
20 | src/main/webapp/conf.html
21 | target/
22 | *.iml
23 |
--------------------------------------------------------------------------------
/src/main/scala/code/snippet/TimeHelpers.scala:
--------------------------------------------------------------------------------
1 | package code.snippet
2 |
3 | import java.text.SimpleDateFormat
4 | import java.util.Calendar
5 |
6 | import net.liftweb.util.Helpers._
7 |
8 | /**
9 | * So we can put the current year in a template
10 | */
11 |
12 | class TimeHelpers {
13 |
14 | val now = Calendar.getInstance().getTime()
15 | // create the date/time formatter
16 | val yearFormat = new SimpleDateFormat("yyyy")
17 | val nowYear = yearFormat.format(now)
18 |
19 | def currentYear = "#current_year" #> nowYear.toString
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/scala/code/Constant.scala:
--------------------------------------------------------------------------------
1 | package code
2 |
3 | import net.liftweb.util.Props
4 |
5 | object Constant {
6 | final val CUSTOM_OWNER_VIEW_ID = "owner"
7 | final val versionOfApi = Props.get("api_version").getOrElse("v4.0.0")
8 | final val versionOfApi121 = "v1.2.1"
9 | final val correlatedUserIdTargetCookieName = "CORRELATED_USER_ID_TARGET"
10 | final val correlatedUserIdBoundCookieName = "CORRELATED_USER_ID_BOUND"
11 | final val correlatedCustomerIdCreatedCookieName = "CORRELATED_CUSTOMER_ID_CREATED"
12 | final val linkBetweenCorrelatedUserAndCustomerCreatedCookieName = "LINK_BETWEEN_CORRELATED_USER_AND_CUSTOMER_CREATED"
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 | LiftFilter
10 | Lift Filter
11 | The Filter that intercepts lift calls
12 | net.liftweb.http.LiftFilter
13 |
14 |
15 |
16 |
17 | LiftFilter
18 | /*
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | Open Bank Project - Sofi Web Application
2 | Copyright (C) 2011, 2012, TESOBE GmbH.
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with this program. If not, see .
16 |
17 | Email: contact@tesobe.com
18 | TESOBE GmbH.
19 | Osloer Str. 16/17
20 | Berlin 13359, Germany
21 |
22 | This product includes software developed at
23 | TESOBE (http://www.tesobe.com/)
24 | by
25 | Simon Redfern : simon AT tesobe DOT com
26 | Stefan Bethge : stefan AT tesobe DOT com
27 | Everett Sochowski : everett AT tesobe DOT com
28 | Ayoub Benali: ayoub AT tesobe DOT com
29 |
--------------------------------------------------------------------------------
/src/test/scala/LiftConsole.scala:
--------------------------------------------------------------------------------
1 | /**
2 | Open Bank Project
3 |
4 | Copyright 2011,2012 TESOBE GmbH.
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | */
18 | import bootstrap.liftweb.Boot
19 | import scala.tools.nsc.MainGenericRunner
20 | import scala.sys._
21 |
22 | object LiftConsole {
23 | def main(args : Array[String]) {
24 | // Instantiate your project's Boot file
25 | val b = new Boot()
26 | // Boot your project
27 | b.boot
28 | // Now run the MainGenericRunner to get your repl
29 | MainGenericRunner.main(args)
30 | // After the repl exits, then exit the scala script
31 | sys.exit(0)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/resources/i18n/lift-core_en_GB.properties:
--------------------------------------------------------------------------------
1 | login = Login
2 | logout = Logout
3 | views = Views
4 | private_accounts = Private accounts
5 | public_accounts = Public accounts
6 | my_accounts = My accounts
7 | account_name = Account Name
8 | you_are_logged_out = You are logged out. No authorised accounts available.
9 | enter_label = Enter a label...
10 | create_account_label = Create an account
11 | bank_name = Bank name
12 | account_label = Account name
13 | income_description = Description
14 | income_amount = Amount \u20ac
15 | payment_description = Description
16 | payment_amount = Amount \u20ac
17 | income = Income
18 | payment = Expenditure
19 | add_expenditure = Add expenditure
20 | button.save = Save
21 | api_documentation = API Documentation
22 | forgotten_password = Forgotten password?
23 | change_password = Change password
24 | new_label=Label
25 | expenditure.tags=Other,\
26 | Telco&Internet,\
27 | Family care,\
28 | Insurance,\
29 | Health,\
30 | Restaurants,\
31 | Spare time,\
32 | Off line shopping,\
33 | Transport,\
34 | Rent and house,\
35 | On-line shopping,\
36 | Groceries
37 | income.tags=Salary,\
38 | Transfer,\
39 | Refund,\
40 | Cash income,\
41 | Pensions and yields,\
42 | Extra and gifts
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 |
4 | ## Hello!
5 |
6 | Thank you for your interest in contributing to the Open Bank Project!
7 |
8 | ## Pull requests
9 |
10 | If submitting a pull request please read and sign our [CLA](http://github.com/OpenBankProject/OBP-API/blob/develop/Harmony_Individual_Contributor_Assignment_Agreement.txt) and send it to contact@tesobe.com - We'll send you back a code to include in the comment section of subsequent pull requests.
11 |
12 | Please reference Issue Numbers in your commits.
13 |
14 | ## Code comments
15 |
16 | Please comment your code ! :-) Imagine an engineer is trying to fix a production issue: she is working on a tiny screen, via a dodgy mobile Internet connection, in a sandstorm - Your code is fresh in your mind. Your comments could help her!
17 |
18 | ## Issues
19 |
20 | If would like to report an issue or suggest any kind of improvement please use Github Issues.
21 |
22 | ## Licenses
23 |
24 | Open Bank Project API, API Explorer and Sofi are dual licenced under the AGPL and commercial licenses. Open Bank Project SDKs are licenced under Apache 2 or MIT style licences.
25 |
26 | Please see the NOTICE for each project licence.
27 |
28 | ## Setup and Tests
29 |
30 | See the README for instructions on setup :-)
31 |
32 | Welcome!
--------------------------------------------------------------------------------
/src/main/webapp/help.html:
--------------------------------------------------------------------------------
1 |
19 |
20 |
40 |
--------------------------------------------------------------------------------
/src/main/scala/code/util/ExceptionLogger.scala:
--------------------------------------------------------------------------------
1 | package code.util
2 |
3 | import net.liftweb.common.{Failure, Full, Box}
4 | import code.util.Helper.MdcLoggable
5 | import net.liftweb.util.{Mailer, Props}
6 |
7 | object MyExceptionLogger extends MdcLoggable{
8 | import net.liftweb.http.Req
9 |
10 | def unapply(in: (Props.RunModes.Value, Req, Throwable)): Option[(Props.RunModes.Value, Req, Throwable)] = {
11 | import net.liftweb.util.Helpers.now
12 | import Mailer.{From, To, Subject, PlainMailBodyType}
13 |
14 | val outputStream = new java.io.ByteArrayOutputStream
15 | val printStream = new java.io.PrintStream(outputStream)
16 | in._3.printStackTrace(printStream)
17 | val currentTime = now.toString
18 | val stackTrace = new String(outputStream.toByteArray)
19 | val error = currentTime + ": " + stackTrace
20 | val host = Props.get("base_url", "unknown host")
21 |
22 | val mailSent = for {
23 | from <- Props.get("mail.exception.sender.address") ?~ "Could not send mail: Missing props param for 'from'"
24 | // no spaces, comma separated e.g. mail.api.consumer.registered.notification.addresses=notify@example.com,notify2@example.com,notify3@example.com
25 | toAddressesString <- Props.get("mail.exception.registered.notification.addresses") ?~ "Could not send mail: Missing props param for 'to'"
26 | } yield {
27 |
28 | //technically doesn't work for all valid email addresses so this will mess up if someone tries to send emails to "foo,bar"@example.com
29 | val to = toAddressesString.split(",").toList
30 | val toParams = to.map(To(_))
31 | val params = PlainMailBodyType(error) :: toParams
32 |
33 | //this is an async call
34 | Mailer.sendMail(
35 | From(from),
36 | Subject("you got an exception on "+host),
37 | params :_*
38 | )
39 | }
40 |
41 | //if Mailer.sendMail wasn't called (note: this actually isn't checking if the mail failed to send as that is being done asynchronously)
42 | if(mailSent.isEmpty)
43 | logger.warn("Exception notification failed: " +mailSent)
44 |
45 | None
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/scala/RunWebApp.scala:
--------------------------------------------------------------------------------
1 | /**
2 | Open Bank Project - Sofi Web Application
3 | Copyright (C) 2011 - 2021, TESOBE GmbH.
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU Affero General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Affero General Public License for more details.
14 |
15 | You should have received a copy of the GNU Affero General Public License
16 | along with this program. If not, see .
17 |
18 | Email: contact@tesobe.com
19 | TESOBE GmbH.
20 | Osloer Str. 16/17
21 | Berlin 13359, Germany
22 |
23 | This product includes software developed at
24 | TESOBE (http://www.tesobe.com/)
25 | by
26 | Simon Redfern : simon AT tesobe DOT com
27 | Stefan Bethge : stefan AT tesobe DOT com
28 | Everett Sochowski : everett AT tesobe DOT com
29 | Ayoub Benali: ayoub AT tesobe DOT com
30 | */
31 |
32 | import net.liftweb.util.Props
33 | import org.mortbay.jetty.Server
34 | import org.mortbay.jetty.webapp.WebAppContext
35 | import org.mortbay.jetty.nio._
36 |
37 | object RunWebApp extends App {
38 | val server = new Server
39 | val scc = new SelectChannelConnector
40 | scc.setPort(Props.getInt("dev.port", 8080))
41 | server.setConnectors(Array(scc))
42 |
43 | val context = new WebAppContext()
44 | context.setServer(server)
45 | context.setContextPath("/")
46 | context.setWar("src/main/webapp")
47 |
48 | server.addHandler(context)
49 |
50 | try {
51 | println(">>> STARTING EMBEDDED JETTY SERVER, PRESS ANY KEY TO STOP")
52 | server.start()
53 | while (System.in.available() == 0) {
54 | Thread.sleep(5000)
55 | }
56 | server.stop()
57 | server.join()
58 | } catch {
59 | case exc : Exception => {
60 | exc.printStackTrace()
61 | sys.exit(100)
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/webapp/media/js/vendor/jquery.dropdown.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery Dropdown: A simple dropdown plugin
3 | *
4 | * Contribute: https://github.com/claviska/jquery-dropdown
5 | *
6 | * @license: MIT license: http://opensource.org/licenses/MIT
7 | *
8 | */
9 | jQuery&&function($){function t(t,e){var n=t?$(this):e,d=$(n.attr("data-jq-dropdown")),a=n.hasClass("jq-dropdown-open");if(t){if($(t.target).hasClass("jq-dropdown-ignore"))return;t.preventDefault(),t.stopPropagation()}else if(n!==e.target&&$(e.target).hasClass("jq-dropdown-ignore"))return;o(),a||n.hasClass("jq-dropdown-disabled")||(n.addClass("jq-dropdown-open"),d.data("jq-dropdown-trigger",n).show(),r(),d.trigger("show",{jqDropdown:d,trigger:n}))}function o(t){var o=t?$(t.target).parents().addBack():null;if(o&&o.is(".jq-dropdown")){if(!o.is(".jq-dropdown-menu"))return;if(!o.is("A"))return}$(document).find(".jq-dropdown:visible").each(function(){var t=$(this);t.hide().removeData("jq-dropdown-trigger").trigger("hide",{jqDropdown:t})}),$(document).find(".jq-dropdown-open").removeClass("jq-dropdown-open")}function r(){var t=$(".jq-dropdown:visible").eq(0),o=t.data("jq-dropdown-trigger"),r=o?parseInt(o.attr("data-horizontal-offset")||0,10):null,e=o?parseInt(o.attr("data-vertical-offset")||0,10):null;0!==t.length&&o&&t.css(t.hasClass("jq-dropdown-relative")?{left:t.hasClass("jq-dropdown-anchor-right")?o.position().left-(t.outerWidth(!0)-o.outerWidth(!0))-parseInt(o.css("margin-right"),10)+r:o.position().left+parseInt(o.css("margin-left"),10)+r,top:o.position().top+o.outerHeight(!0)-parseInt(o.css("margin-top"),10)+e}:{left:t.hasClass("jq-dropdown-anchor-right")?o.offset().left-(t.outerWidth()-o.outerWidth())+r:o.offset().left+r,top:o.offset().top+o.outerHeight()+e})}$.extend($.fn,{jqDropdown:function(r,e){switch(r){case"show":return t(null,$(this)),$(this);case"hide":return o(),$(this);case"attach":return $(this).attr("data-jq-dropdown",e);case"detach":return o(),$(this).removeAttr("data-jq-dropdown");case"disable":return $(this).addClass("jq-dropdown-disabled");case"enable":return o(),$(this).removeClass("jq-dropdown-disabled")}}}),$(document).on("click.jq-dropdown","[data-jq-dropdown]",t),$(document).on("click.jq-dropdown",o),$(window).on("resize",r)}(jQuery);
--------------------------------------------------------------------------------
/src/main/webapp/templates-hidden/_dashboard_account.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Account Title Left Side
6 |
7 |
Public account
8 |
9 |
10 |
11 |
12 |
27.10.2015
13 |
14 |
15 |
BALANCE
16 |
€53292
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
Account holder
26 |
27 |
28 |
29 |
30 |
31 |
32 |
€400
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/src/main/resources/i18n/lift-core_it_IT.properties:
--------------------------------------------------------------------------------
1 | login = Accedi
2 | logout = Esci
3 | views = Visualizzazioni
4 | private_accounts = Conti privati
5 | public_accounts = Conti pubblici
6 | my_accounts = I miei registri
7 | account_name = Nome utente
8 | you_are_logged_out = Sei disconnesso. Nessun account autorizzato disponibile.
9 | enter_label = Crea un tag
10 | create_account_label = Crea un conto in banca
11 | bank_name = nome della banca
12 | account_label = Etichetta dell'account
13 | income_description = Descrizione del reddito
14 | income_amount = Importo del reddito
15 | payment_description = Descrizione
16 | payment_amount = Importo del pagamento
17 | payment_category = Categoria
18 | income = Reddito
19 | payment = Pagamento
20 | expenditure = Spesa
21 | add_expenditure = Aggiungi una spesa
22 | add_income = Aggiungi un'entrata
23 | button.save = Salva
24 | button_cancel = Annulla
25 | button_show = Vedi
26 | api_documentation = Documentazione API
27 | forgotten_password = Hai dimenticato la password?
28 | change_password = Cambia la password
29 | expenditure.tags=Spesa alimentari,\
30 | Telefono e Internet,\
31 | Spese familiari,\
32 | Assicurazioni,\
33 | Spese mediche,\
34 | Ristorante,\
35 | Tempo libero,\
36 | Acquisiti in negozio,\
37 | Trasporti,\
38 | Casa,\
39 | Acquisti on line,\
40 | Extra e imprevisti
41 | income.tags=Stipendio,\
42 | Bonifico,\
43 | Rimborso spese,\
44 | Entrate in contanti,\
45 | Rendita e pensione,\
46 | Extra e regali
47 | months_ago = Periodo
48 | about = Chi siamo
49 | help_info = Se desiderate accedere o modificare i vostri dati personali o richiedere la cancellazione, l'esportazione o il trasferimento delle informazioni che vi riguardano, potete inviarci un'e-mail con la vostra richiesta a gdpr@microfinanza.it
50 | balance = Bilancio
51 | balance_colon = Bilancio:
52 | add_tag = aggiungi un tag
53 | add_image = aggiungi un'immagine
54 | add_comment = aggiungi un commento
55 | images = Immagini
56 | add_a_new_image = aggiungi una nuova immagine
57 | tags = Tag
58 | comments = Commenti
59 | add_a_comment = Aggiungi un commento qui
60 | months_ago_list = 1::mese,2::mesi,3::mesi,4::mesi,5::mesi,6::mesi,7::mesi,8::mesi,9::mesi,10::mesi,11::mesi,12::mesi
61 | profile_completeness = Completezza del profilo
62 | credit_score = Punteggio di credito
--------------------------------------------------------------------------------
/src/main/webapp/media/css/highlight.js.min.css:
--------------------------------------------------------------------------------
1 | .hljs{display:block;overflow-x:auto;padding:0.5em;background:#f0f0f0;-webkit-text-size-adjust:none}.hljs,.hljs-subst,.hljs-tag .hljs-title,.nginx .hljs-title{color:black}.hljs-string,.hljs-title,.hljs-constant,.hljs-parent,.hljs-tag .hljs-value,.hljs-rule .hljs-value,.hljs-preprocessor,.hljs-pragma,.hljs-name,.haml .hljs-symbol,.ruby .hljs-symbol,.ruby .hljs-symbol .hljs-string,.hljs-template_tag,.django .hljs-variable,.smalltalk .hljs-class,.hljs-addition,.hljs-flow,.hljs-stream,.bash .hljs-variable,.pf .hljs-variable,.apache .hljs-tag,.apache .hljs-cbracket,.tex .hljs-command,.tex .hljs-special,.erlang_repl .hljs-function_or_atom,.asciidoc .hljs-header,.markdown .hljs-header,.coffeescript .hljs-attribute,.tp .hljs-variable{color:#800}.smartquote,.hljs-comment,.hljs-annotation,.diff .hljs-header,.hljs-chunk,.asciidoc .hljs-blockquote,.markdown .hljs-blockquote{color:#888}.hljs-number,.hljs-date,.hljs-regexp,.hljs-literal,.hljs-hexcolor,.smalltalk .hljs-symbol,.smalltalk .hljs-char,.go .hljs-constant,.hljs-change,.lasso .hljs-variable,.makefile .hljs-variable,.asciidoc .hljs-bullet,.markdown .hljs-bullet,.asciidoc .hljs-link_url,.markdown .hljs-link_url{color:#080}.hljs-label,.ruby .hljs-string,.hljs-decorator,.hljs-filter .hljs-argument,.hljs-localvars,.hljs-array,.hljs-attr_selector,.hljs-important,.hljs-pseudo,.hljs-pi,.haml .hljs-bullet,.hljs-doctype,.hljs-deletion,.hljs-envvar,.hljs-shebang,.apache .hljs-sqbracket,.nginx .hljs-built_in,.tex .hljs-formula,.erlang_repl .hljs-reserved,.hljs-prompt,.asciidoc .hljs-link_label,.markdown .hljs-link_label,.vhdl .hljs-attribute,.clojure .hljs-attribute,.asciidoc .hljs-attribute,.lasso .hljs-attribute,.coffeescript .hljs-property,.hljs-phony{color:#88f}.hljs-keyword,.hljs-id,.hljs-title,.hljs-built_in,.css .hljs-tag,.hljs-doctag,.smalltalk .hljs-class,.hljs-winutils,.bash .hljs-variable,.pf .hljs-variable,.apache .hljs-tag,.hljs-type,.hljs-typename,.tex .hljs-command,.asciidoc .hljs-strong,.markdown .hljs-strong,.hljs-request,.hljs-status,.tp .hljs-data,.tp .hljs-io{font-weight:bold}.asciidoc .hljs-emphasis,.markdown .hljs-emphasis,.tp .hljs-units{font-style:italic}.nginx .hljs-built_in{font-weight:normal}.coffeescript .javascript,.javascript .xml,.lasso .markup,.tex .hljs-formula,.xml .javascript,.xml .vbscript,.xml .css,.xml .hljs-cdata{opacity:0.5}
--------------------------------------------------------------------------------
/src/main/scala/code/snippet/CreateBankAccount.scala:
--------------------------------------------------------------------------------
1 | package code.snippet
2 |
3 | import code.lib.ObpAPI
4 | import code.lib.ObpAPI.createAccount
5 | import code.lib.ObpJson.BankJson400
6 | import code.util.Helper.MdcLoggable
7 | import net.liftweb.common.Box
8 | import net.liftweb.http.js.JE.Call
9 | import net.liftweb.http.js.JsCmd
10 | import net.liftweb.http.js.JsCmds.SetHtml
11 | import net.liftweb.http.{RequestVar, SHtml}
12 | import net.liftweb.util.Helpers._
13 |
14 | import scala.collection.immutable.List
15 | import scala.xml.{NodeSeq, Text}
16 |
17 |
18 | class CreateBankAccount(params: List[BankJson400]) extends MdcLoggable {
19 |
20 | private object bankVar extends RequestVar("")
21 | private object userIdVar extends RequestVar("")
22 |
23 |
24 | def editLabel(xhtml: NodeSeq): NodeSeq = {
25 | var newLabel = ""
26 | val bankId = "user." + ObpAPI.currentUser.map(_.user_id).getOrElse(System.currentTimeMillis())
27 | val listOfBanks = params
28 | .filter(_.id == bankId)
29 | .map(b => (b.id, b.full_name))
30 |
31 | def process(): JsCmd = {
32 | ObpAPI.currentUser.map {
33 | u => userIdVar.set(u.user_id)
34 | }
35 | logger.debug(s"CreateBankAccount.editLabel.process: edit label $newLabel")
36 | if(listOfBanks.size == 1) {
37 | val result = createAccount(bankVar.is, newLabel, userIdVar.is)
38 | if (result.isDefined) {
39 | val msg = "Saved"
40 | SetHtml("account-title", Text(newLabel)) &
41 | Call("socialFinanceNotifications.notify", msg).cmd
42 | } else {
43 | val msg = "Sorry, the new account with the label" + newLabel + " could not be set ("+ result +")"
44 | Call("socialFinanceNotifications.notifyError", msg).cmd
45 | }
46 | } else {
47 | val msg = "Sorry, the new account with the label " + newLabel + " could not be set due to unresolved bank id value"
48 | Call("socialFinanceNotifications.notifyError", msg).cmd
49 | }
50 | }
51 |
52 | (
53 | "@new_label" #> SHtml.text("", s => newLabel = s) &
54 | "#bank-id" #> SHtml.select(listOfBanks, Box!! bankVar.is, bankVar(_)) &
55 | // Replace the type=submit with Javascript that makes the ajax call.
56 | "type=submit" #> SHtml.ajaxSubmit("Create", process)
57 | ).apply(xhtml)
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/scala/code/snippet/CreateExpenditure.scala:
--------------------------------------------------------------------------------
1 | package code.snippet
2 |
3 | import code.Constant._
4 | import code.lib.ObpAPI
5 | import code.lib.ObpAPI.{createOutcome, getAccount}
6 | import code.util.Helper.{MdcLoggable, getAccountTitle}
7 | import net.liftweb.common.Box
8 | import net.liftweb.http.js.JE.Call
9 | import net.liftweb.http.js.JsCmd
10 | import net.liftweb.http.{RequestVar, S, SHtml}
11 | import net.liftweb.util.Helpers._
12 |
13 | import scala.xml.NodeSeq
14 |
15 |
16 | class CreateExpenditure(params: List[String]) extends MdcLoggable {
17 | private object tagVar extends RequestVar("")
18 | val bankId = params(0)
19 | val accountId = params(1)
20 | val accountJson = getAccount(bankId, accountId, CUSTOM_OWNER_VIEW_ID).openOrThrowException("Could not open accountJson")
21 | def accountTitle = ".account-title *" #> getAccountTitle(accountJson)
22 |
23 |
24 | def addPayment(xhtml: NodeSeq): NodeSeq = {
25 | var outcomeDescription = ""
26 | var outcomeAmount = 0D
27 | val listOfTags: Seq[(String, String)] = S.?("expenditure.tags").
28 | split(",").toList.map(_.trim).map(i => i.replaceAll("_", "/")).map(i => (i,i))
29 |
30 | def process(): JsCmd = {
31 | logger.debug(s"CreateOutcome.addOutcome.process: edit label $outcomeDescription")
32 | val result = createOutcome(bankId, accountId, outcomeDescription, outcomeAmount.toString, "EUR")
33 | if (result.isDefined) {
34 | val transactionId = result.map(_.transaction_id).getOrElse("")
35 | val addTags = ObpAPI.addTags(bankId, accountId, "owner", transactionId, List(tagVar.is))
36 | logger.debug(s"CreateOutcome.addOutcome.process.addTags $addTags")
37 | val msg = "Saved"
38 | Call("socialFinanceNotifications.notify", msg).cmd
39 | S.redirectTo(s"/banks/$bankId/accounts/$accountId/owner")
40 | } else {
41 | val msg = s"Sorry, Expenditure $outcomeDescription could not be added ($result)"
42 | Call("socialFinanceNotifications.notifyError", msg).cmd
43 | }
44 | }
45 |
46 | (
47 | "@payment_description" #> SHtml.text("", s => outcomeDescription = s) &
48 | "#payment_category" #> SHtml.select(listOfTags, Box!! tagVar.is, tagVar(_)) &
49 | "@payment_amount" #> SHtml.number(0D, (s:Double) => outcomeAmount = s, 0D, 1000000000D, 0.01D) &
50 | // Replace the type=submit with Javascript that makes the ajax call.
51 | "type=submit" #> SHtml.ajaxSubmit(S.?("button.save"), process)
52 | ).apply(xhtml)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/resources/i18n/lift-core.properties:
--------------------------------------------------------------------------------
1 | login = Login
2 | logout = Logout
3 | views = Views
4 | private_accounts = Private accounts
5 | public_accounts = Public accounts
6 | my_accounts = My accounts
7 | account_name = Account Name
8 | you_are_logged_out = You are logged out. No authorised accounts available.
9 | enter_label = Enter a label...
10 | create_account_label = Create new account
11 | bank_name = Bank name
12 | #account_label = Account label
13 | account_label = Account name
14 | income_description = Description
15 | income_amount = Amount \u20ac
16 | payment_description = Description
17 | payment_amount = Amount \u20ac
18 | payment_category = Category
19 | income = Income
20 | payment = Expenditure
21 | expenditure = Expenditure
22 | add_expenditure = Add expenditure
23 | add_income = Add income
24 | button.save = Save
25 | button_cancel = Cancel
26 | button_show = Show
27 | api_documentation = API Documentation
28 | forgotten_password = Forgotten password?
29 | change_password = Change password
30 | new_label=Label
31 | expenditure.tags=Other,\
32 | Telco&Internet,\
33 | Family care,\
34 | Insurance,\
35 | Health,\
36 | Restaurants,\
37 | Spare time,\
38 | Off line shopping,\
39 | Transport,\
40 | Rent and house,\
41 | On-line shopping,\
42 | Groceries
43 | income.tags=Salary,\
44 | Transfer,\
45 | Refund,\
46 | Cash income,\
47 | Pensions and yields,\
48 | Extra and gifts
49 | months_ago = Period
50 | about = About
51 | about_info = Welcome to the IncludiMI App. IncludiMI is an innovative project which aims to provide financial identity to the underbanked. IncludiMI is led by Experian, Associazione Microfinanza e Sviluppo ONLUS, Associazione MicroLab and TESOBE.
52 | help_info = If you wish to access or amend any Personal Data we hold about you, or to request that we delete, export or transfer any information about you, you may email us with your request at dpoitaly@experian.com
53 | help = Help
54 | balance = Balance
55 | balance_colon = Balance:
56 | add_tag = ADD TAG
57 | add_image = ADD IMAGE
58 | add_comment = ADD COMMENT
59 | images = Images
60 | add_a_new_image = Add a new iage
61 | tags = Tags
62 | comments = Comments
63 | add_a_comment = Add a comment here
64 | months_ago_list = 1::month,2::months,3::months,4::months,5::months,6::months,7::months,8::months,9::months,10::months,11::months,12::months
65 | profile_completeness = Profile completeness
66 | credit_score = Credit score
67 | source_code_text = The source code for this application is available here:
68 | debug_info_text = Data we store related to your account includes the following:
69 |
--------------------------------------------------------------------------------
/src/main/webapp/banks/star/accounts/star/settings.html:
--------------------------------------------------------------------------------
1 |
29 |
30 |
34 |
35 |
66 |
--------------------------------------------------------------------------------
/src/main/scala/code/snippet/Login.scala:
--------------------------------------------------------------------------------
1 | /**
2 | Open Bank Project - Sofi Web Application
3 | Copyright (C) 2011 - 2021, TESOBE GmbH
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU Affero General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Affero General Public License for more details.
14 |
15 | You should have received a copy of the GNU Affero General Public License
16 | along with this program. If not, see .
17 |
18 | Email: contact@tesobe.com
19 | TESOBE GmbH.
20 | Osloer Str. 16/17
21 | Berlin 13359, Germany
22 |
23 | This product includes software developed at
24 | TESOBE (http://www.tesobe.com/)
25 | by
26 | Simon Redfern : simon AT tesobe DOT com
27 | Stefan Bethge : stefan AT tesobe DOT com
28 | Everett Sochowski : everett AT tesobe DOT com
29 | Ayoub Benali: ayoub AT tesobe DOT com
30 |
31 | */
32 |
33 | package code.snippet
34 |
35 | import code.Constant
36 | import code.lib.{OAuthClient, ObpAPI}
37 | import code.util.Helper.MdcLoggable
38 | import code.util.{Helper, Util}
39 | import net.liftweb.common.{Box, Full}
40 | import net.liftweb.http.js.JsCmd
41 | import net.liftweb.http.js.JsCmds.Noop
42 | import net.liftweb.http.provider.HTTPCookie
43 | import net.liftweb.http.{S, SHtml}
44 | import net.liftweb.util.Helpers._
45 |
46 | class Login extends MdcLoggable {
47 |
48 |
49 | private def loggedIn = {
50 | // Correlated User ID Flow
51 | S.cookieValue(Constant.correlatedUserIdTargetCookieName) match {
52 | case Full(correlatedUserId) if correlatedUserId != null =>
53 | // This will do the full correlatedUserFlow
54 | logger.debug("Expecting full correlatedUserFlow")
55 | Util.correlatedUserFlow(Some(correlatedUserId))
56 | case _ =>
57 | // This will do the partial correlatedUserFlow i.e. maybe add a customer and user customer link
58 | logger.debug("Expecting partial correlatedUserFlow")
59 | Util.correlatedUserFlow(None)
60 | }
61 | def getDisplayNameOfUser(): Box[String] = {
62 | ObpAPI.currentUser.map {
63 | u =>
64 | u.provider.toLowerCase() match {
65 | case provider if provider.contains("google") => u.email
66 | case provider if provider.contains("yahoo") => u.email
67 | case _ => u.username
68 | }
69 | }
70 | }
71 | ".logged-out *" #> "" &
72 | "#logged-in-name *" #> getDisplayNameOfUser() &
73 | "#logout [onclick+]" #> SHtml.onEvent(s => {
74 | OAuthClient.logoutAll()
75 | Noop
76 | })
77 | }
78 |
79 | def loggedOut = {
80 | ".logged-in *" #> "" &
81 | "#start-login [onclick]" #> {
82 | def actionJS: JsCmd = {
83 | OAuthClient.redirectToOauthLogin()
84 | Noop
85 | }
86 | SHtml.onEvent((s: String) => actionJS)
87 | }
88 | }
89 |
90 | def login = {
91 | if(OAuthClient.loggedIn) loggedIn
92 | else loggedOut
93 | }
94 |
95 |
96 |
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/webapp/media/js/toastr.min.js:
--------------------------------------------------------------------------------
1 | (function(n){n(["jquery"],function(n){return function(){function l(n,t,f){return u({type:r.error,iconClass:i().iconClasses.error,message:n,optionsOverride:f,title:t})}function a(n,t,f){return u({type:r.info,iconClass:i().iconClasses.info,message:n,optionsOverride:f,title:t})}function v(n){e=n}function y(n,t,f){return u({type:r.success,iconClass:i().iconClasses.success,message:n,optionsOverride:f,title:t})}function p(n,t,f){return u({type:r.warning,iconClass:i().iconClasses.warning,message:n,optionsOverride:f,title:t})}function w(r){var u=i();if(t||f(u),r&&n(":focus",r).length===0){r[u.hideMethod]({duration:u.hideDuration,easing:u.hideEasing,complete:function(){c(r)}});return}t.children().length&&t[u.hideMethod]({duration:u.hideDuration,easing:u.hideEasing,complete:function(){t.remove()}})}function b(){return{tapToDismiss:!0,toastClass:"toast",containerId:"toast-container",debug:!1,showMethod:"fadeIn",showDuration:300,showEasing:"swing",onShown:undefined,hideMethod:"fadeOut",hideDuration:1e3,hideEasing:"swing",onHidden:undefined,extendedTimeOut:1e3,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},iconClass:"toast-info",positionClass:"toast-top-right",timeOut:5e3,titleClass:"toast-title",messageClass:"toast-message",target:"body",closeHtml:"