From 44de8bc4487bd728a44e12b4d66bf24c1fb10951 Mon Sep 17 00:00:00 2001 From: Chakib Benziane Date: Sun, 7 Apr 2019 22:31:35 +0200 Subject: [PATCH] Working download !!! --- api/download.go | 85 ++++++++++++++++++++--------- api/handlers.go | 67 ++++++++++++++++++----- api/upload_ctrl.go | 29 +++++----- db/redis_utils.go | 13 +++++ ln/invoice.go | 8 +++ storage/upload_model.go | 66 +++++++++++++--------- storage/zip.go | 57 +++++++++++++++++++ watchers/invoices.go | 115 +++++++++++++++++++++------------------ web/src/DownloadView.vue | 32 ++++++++++- web/src/api.js | 18 +++++- 10 files changed, 350 insertions(+), 140 deletions(-) create mode 100644 db/redis_utils.go create mode 100644 storage/zip.go diff --git a/api/download.go b/api/download.go index acf7798..9897097 100644 --- a/api/download.go +++ b/api/download.go @@ -7,11 +7,13 @@ import ( "net/http" "time" + "git.sp4ke.com/sp4ke/bit4sat/db" "git.sp4ke.com/sp4ke/bit4sat/ln" "git.sp4ke.com/sp4ke/bit4sat/storage" "git.sp4ke.com/sp4ke/bit4sat/utils" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" + "github.com/mediocregopher/radix/v3" ) func download(c *gin.Context) { @@ -26,6 +28,14 @@ func download(c *gin.Context) { return } + // Get files metadata for upload + var upFilesMeta []storage.FileUpload + upFilesMeta, err = storage.GetUploadFilesMeta(upId) + if err != nil { + utils.JSONErrPriv(c, http.StatusInternalServerError, err) + return + } + // Get the download session session, err := SessionStore.Get(c.Request, DlSessionKey) if err != nil { @@ -80,16 +90,6 @@ func download(c *gin.Context) { return } - // Get files metadata for upload - var upFilesMeta []storage.FileUpload - upFilesMeta, err = storage.GetUploadFilesMeta(upId) - if err != nil { - utils.JSONErrPriv(c, http.StatusInternalServerError, err) - return - } - - session.Values["files"] = upFilesMeta - invoiceOpts := ln.InvoiceOpts{ Amount: up.AskAmount, Curr: ln.CurrencyID[up.AskCurrency], @@ -104,10 +104,20 @@ func download(c *gin.Context) { return } - // Store invoice + // Store invoice_id ---> upload_id + key := fmt.Sprintf("invoice_id_%s_upload_id", invoice.RHash) + err = db.DB.Redis.Do(radix.FlatCmd(nil, "SET", key, upId)) + if err != nil { + utils.JSONErrPriv(c, http.StatusInternalServerError, err) + return + } + + // Store invoice_ + invoiceKey := fmt.Sprintf("invoice_%s", invoice.RHash) + err = db.DB.Redis.Do(radix.FlatCmd(nil, "SET", invoiceKey, invoice)) session.Values["session-id"] = sessId - session.Values["invoice"] = invoice + session.Values["invoice-id"] = invoice.RHash invoiceExpires := time.Time(invoice.ExpiresAt).Sub(time.Now()).Seconds() @@ -131,10 +141,9 @@ func download(c *gin.Context) { } else { log.Printf("continue download session id: %s", dlSess) - invVal := session.Values["invoice"] - var invoice = &ln.Invoice{} - if invoice, ok = invVal.(*ln.Invoice); !ok { - log.Printf("Could not find invoice in session %s", dlSess) + // Get invoice-id linked to sessionId + invIdVal := session.Values["invoice-id"] + if invIdVal == nil { session.Options.MaxAge = -1 err = session.Save(c.Request, c.Writer) @@ -148,14 +157,9 @@ func download(c *gin.Context) { return } - //TODO: Check if invoice paid ?? - - //If paid return the files else return the invoice to pay - - filesVal := session.Values["files"] - var filesMeta = &[]storage.FileUpload{} - if filesMeta, ok = filesVal.(*[]storage.FileUpload); !ok { - // The cookie broke ??? + var invoiceId string + if invoiceId, ok = invIdVal.(string); !ok { + log.Printf("Could not find invoice in session %s", dlSess) session.Options.MaxAge = -1 err = session.Save(c.Request, c.Writer) @@ -165,13 +169,42 @@ func download(c *gin.Context) { } utils.JSONErr(c, http.StatusExpectationFailed, - "start a new download session session") + "invoice not found, start a new download session session") + return + } + + // Get invoice from invoice_id + invoiceKey := fmt.Sprintf("invoice_%s", invoiceId) + invoice := ln.Invoice{} + err = db.DB.Redis.Do(radix.FlatCmd(&invoice, "GET", invoiceKey)) + if err != nil { + utils.JSONErrPriv(c, http.StatusInternalServerError, err) + return + } + + // If invoice paid send the files + if invoice.Settled { + log.Println("dl invoice paid, sending") + + // set response type to zip mime type + c.Header("Content-Type", "application/zip") + c.Header("Content-Disposition", "attachment; filename=download.zip") + + err := storage.ZipFiles(upFilesMeta, c.Writer) + if err != nil { + log.Fatal(err) + } + + //c.JSON(http.StatusOK, gin.H{ + //"download": "ok", + //"invoice": invoice, + //}) return } c.JSON(http.StatusPaymentRequired, gin.H{ "invoice": invoice, - "files": filesMeta, + "files": upFilesMeta, }) } diff --git a/api/handlers.go b/api/handlers.go index b3c8b84..ab37d75 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -7,7 +7,6 @@ import ( "git.sp4ke.com/sp4ke/bit4sat/db" "git.sp4ke.com/sp4ke/bit4sat/ln" - "git.sp4ke.com/sp4ke/bit4sat/lndrpc" "git.sp4ke.com/sp4ke/bit4sat/storage" "git.sp4ke.com/sp4ke/bit4sat/utils" "github.com/gin-gonic/gin" @@ -73,25 +72,63 @@ func pollInvoice(c *gin.Context) { invoiceId := c.Param("rhash") // First check if already paid - lnInv, err := lndrpc.LookupInvoiceRhashStr(invoiceId) + + // Get the invoice from invoice_id + invoiceKey := fmt.Sprintf("invoice_%s", invoiceId) + invoice := ln.Invoice{} + err := db.DB.Redis.Do(radix.FlatCmd(&invoice, "GET", invoiceKey)) if err != nil { - log.Println(err) - utils.JSONErr(c, http.StatusNotFound, - "invoice not found !") + utils.JSONErrPriv(c, http.StatusInternalServerError, err) return } - invoice := ln.InvoiceFromLndIn(lnInv) - - res := gin.H{ - "invoice": invoice, - } - // If paid return ok - if lnInv.Settled { - c.JSON(http.StatusOK, res) + if invoice.Settled { + c.JSON(http.StatusOK, gin.H{ + "invoice": invoice, + }) + + // Poll } else { - c.JSON(http.StatusPaymentRequired, res) + + invoiceChan := make(chan *ln.Invoice) + errorChan := make(chan error) + + log.Printf("starting invoice poll for %s", invoice.RHash) + // If waiting payment, wait until invoice is paid + go ln.PollPaidInvoice(invoice.RHash, invoiceChan, errorChan) + select { + case invoice := <-invoiceChan: + + // if expired return with expired response + if invoice.Expired { + + c.JSON(http.StatusGone, gin.H{ + "invoice": invoice, + }) + + return + } + + //////////////// + ///// Invoice was paid + //////////////// + // + log.Println("POLL: invoice was paid") + + c.JSON(http.StatusOK, gin.H{ + "invoice": invoice, + }) + + case err := <-errorChan: + utils.JSONErrPriv(c, http.StatusInternalServerError, err) + } + + // We stopped waiting for the invoice, it must have expired + c.JSON(http.StatusGone, gin.H{ + "invoice": invoice, + }) + } return @@ -115,7 +152,7 @@ func invoiceCbHandler(c *gin.Context) { // get upload id related to invoice var uploadId string - invoiceUploadKey := fmt.Sprintf("invoice_%s_upload", invoice.RHash) + invoiceUploadKey := fmt.Sprintf("invoice_%s_uploadid", invoice.RHash) err := db.DB.Redis.Do(radix.FlatCmd(&uploadId, "GET", invoiceUploadKey)) if err != nil { diff --git a/api/upload_ctrl.go b/api/upload_ctrl.go index ff56204..76736bf 100644 --- a/api/upload_ctrl.go +++ b/api/upload_ctrl.go @@ -289,21 +289,6 @@ func (ctrl UploadCtrl) PollStatus(c *gin.Context) { case invoice := <-invoiceChan: log.Printf("poll: received invoice notif %s", invoice.RHash) - // if expired return with expired response - if invoice.Expired { - err := storage.SetUploadStatus(uploadId, storage.UpPayExpired) - if err != nil { - log.Printf("Redis error: %s", err) - } - - c.JSON(http.StatusGone, gin.H{ - "status": uploadStatus, - "invoice": invoice, - }) - - return - } - //////////////// ///// Invoice was paid //////////////// @@ -368,8 +353,22 @@ func (ctrl UploadCtrl) PollStatus(c *gin.Context) { case err := <-errorChan: utils.JSONErrPriv(c, http.StatusInternalServerError, err) + return } + // We stopped waiting for the invoice, it must have expired + err := storage.SetUploadStatus(uploadId, storage.UpPayExpired) + if err != nil { + log.Printf("Redis error: %s", err) + } + + c.JSON(http.StatusGone, gin.H{ + "status": uploadStatus, + "invoice": invoice, + }) + + return + } else { c.JSON(http.StatusOK, gin.H{ "status": uploadStatus, diff --git a/db/redis_utils.go b/db/redis_utils.go new file mode 100644 index 0000000..577fe92 --- /dev/null +++ b/db/redis_utils.go @@ -0,0 +1,13 @@ +package db + +import ( + "github.com/mediocregopher/radix/v3" +) + +func GetFromKey(key string, target interface{}) error { + return DB.Redis.Do(radix.FlatCmd(target, "GET", key)) +} + +func SetKeyVal(key string, val interface{}) error { + return DB.Redis.Do(radix.FlatCmd(nil, "SET", key, val)) +} diff --git a/ln/invoice.go b/ln/invoice.go index 516a694..e0eee11 100644 --- a/ln/invoice.go +++ b/ln/invoice.go @@ -180,3 +180,11 @@ func UpdateInvoiceFromLnd(storedIn *Invoice, newIn *lnrpc.Invoice) *Invoice { return storedIn } + +func IsExpiredInvoice(creation, expiry int64) bool { + createdAt := time.Unix(int64(creation), 0) + expiresAt := createdAt.Add(time.Second * time.Duration(expiry)) + + return time.Now().After(expiresAt) + +} diff --git a/storage/upload_model.go b/storage/upload_model.go index adba932..6ce7904 100644 --- a/storage/upload_model.go +++ b/storage/upload_model.go @@ -56,10 +56,19 @@ const ( ); ` + DBUploadPayments = ` + CREATE TABLE IF NOT EXISTS upload_payments ( + payment_id_rhash varchar(64) PRIMARY KEY, + upload_id text NOT NULL references uploads(upload_id), + msat_amount real NOT NULL, + created timestamp DEFAULT now() + ); + ` + + //TODO: store all invoices from redis to local sqldb DBInvoicesSchema = ` CREATE TABLE IF NOT EXISTS invoices ( - rhash varchar(64) PRIMARY KEY, - payload text DEFAULT '' + rhash varchar(64) PRIMARY KEY ); ` @@ -256,6 +265,16 @@ func (u *FileUpload) UnmarshalBinary(b []byte) error { //func SyncUploadStatusToDB(){ //} +// +func AddPaymentToUpload(uploadId string, rhash string, msatAmount float64) error { + query := `INSERT INTO + upload_payments (payment_id_rhash, upload_id, msat_amount) + VALUES ($1, $2, $3) + ` + _, err := DB.Sql.Exec(query, rhash, uploadId, msatAmount) + + return err +} func GetDownloadId(uploadId string) (string, error) { key := fmt.Sprintf("download_for_upload_%s", uploadId) @@ -285,9 +304,9 @@ func GetDownloadId(uploadId string) (string, error) { } // Store it back on redis cache - err = DB.Redis.Do(radix.FlatCmd(nil, "SET", key, downloadId)) + err = db.SetKeyVal(key, downloadId) } else { - err = DB.Redis.Do(radix.FlatCmd(&downloadId, "GET", key)) + err = db.GetFromKey(key, &downloadId) } return downloadId, err @@ -321,9 +340,9 @@ func GetUploadIdForDlId(dlId string) (string, error) { } // Store it back on redis cache - err = DB.Redis.Do(radix.FlatCmd(nil, "SET", key, upId)) + err = db.SetKeyVal(key, upId) } else { - err = DB.Redis.Do(radix.FlatCmd(&upId, "GET", key)) + err = db.GetFromKey(key, &upId) } return upId, err @@ -334,11 +353,13 @@ func GetUploadInvoice(uploadId string) (*ln.Invoice, error) { uploadInvoiceKey := fmt.Sprintf("upload_%s_invoice", uploadId) - err := DB.Redis.Do(radix.FlatCmd(&invoice, "GET", uploadInvoiceKey)) + err := db.GetFromKey(uploadInvoiceKey, &invoice) if err != nil { return nil, err } + log.Printf("GetUploadInvoice returned %#v") + return &invoice, nil } @@ -394,11 +415,11 @@ func GetUploadById(id string) (*Upload, error) { } // Sotre it back on redis - err = DB.Redis.Do(radix.FlatCmd(nil, "SET", key, up)) + err = db.SetKeyVal(key, up) // Get it from redis } else { - err = DB.Redis.Do(radix.FlatCmd(&up, "GET", key)) + err = db.GetFromKey(key, &up) } return &up, err @@ -447,14 +468,14 @@ func GetUploadStatus(id string) (status UpStatus, err error) { key := fmt.Sprintf("upload_status_%s", id) - err = DB.Redis.Do(radix.FlatCmd(&status, "GET", key)) + err = db.GetFromKey(key, &status) return } func SetUploadAdminToken(uploadId, token string) error { key := fmt.Sprintf("upload_admin_%s", uploadId) - err := DB.Redis.Do(radix.FlatCmd(nil, "SET", key, token)) + err := db.SetKeyVal(key, token) if err != nil { return err } @@ -467,26 +488,21 @@ func SetUploadAdminToken(uploadId, token string) error { func GetUploadAdminToken(uploadId string) (string, error) { var token string key := fmt.Sprintf("upload_admin_%s", uploadId) - err := DB.Redis.Do(radix.FlatCmd(&token, "GET", key)) + err := db.GetFromKey(key, &token) return token, err } func SetUploadInvoice(uploadId string, invoice *ln.Invoice) error { uploadInvoiceKey := fmt.Sprintf("upload_%s_invoice", uploadId) - invoiceJson, err := json.Marshal(invoice) - if err != nil { - return err - } - - err = DB.Redis.Do(radix.FlatCmd(nil, "SET", uploadInvoiceKey, invoiceJson)) + err := db.SetKeyVal(uploadInvoiceKey, invoice) if err != nil { return err } // Set inverse relation - invoiceUploadKey := fmt.Sprintf("invoice_%s_upload", invoice.RHash) - err = DB.Redis.Do(radix.FlatCmd(nil, "SET", invoiceUploadKey, uploadId)) + invoiceUploadKey := fmt.Sprintf("invoice_%s_upload_id", invoice.RHash) + err = db.SetKeyVal(invoiceUploadKey, uploadId) if err != nil { return err } @@ -498,11 +514,11 @@ func SetUploadInvoice(uploadId string, invoice *ln.Invoice) error { } // Add invoice to invoices table - query := `INSERT INTO invoices(rhash, payload) - VALUES($1,$2) + query := `INSERT INTO invoices(rhash) + VALUES($1) ON CONFLICT DO NOTHING ` - _, err = tx.Exec(query, invoice.RHash, invoiceJson) + _, err = tx.Exec(query, invoice.RHash) if err != nil { return err } @@ -518,9 +534,9 @@ func SetUploadInvoice(uploadId string, invoice *ln.Invoice) error { } func GetUploadIdForInvoice(invoiceId string) (string, error) { - key := fmt.Sprintf("invoice_%s_upload", invoiceId) + key := fmt.Sprintf("invoice_%s_upload_id", invoiceId) - err := DB.Redis.Do(radix.FlatCmd(&invoiceId, "GET", key)) + err := db.GetFromKey(key, &invoiceId) return invoiceId, err } diff --git a/storage/zip.go b/storage/zip.go new file mode 100644 index 0000000..4f738c1 --- /dev/null +++ b/storage/zip.go @@ -0,0 +1,57 @@ +package storage + +import ( + "archive/zip" + "io" + "os" +) + +func ZipFiles(files []FileUpload, w io.Writer) error { + zipWriter := zip.NewWriter(w) + defer zipWriter.Close() + + // Add files to zip + for _, file := range files { + if err := AddFileToZip(zipWriter, file); err != nil { + return err + } + } + + return nil +} + +// https://golangcode.com/create-zip-files-in-go/ +func AddFileToZip(zipWriter *zip.Writer, file FileUpload) error { + fileToZip, err := os.Open(GetStoreDestination(file.SHA256 + file.FileExt)) + if err != nil { + return err + } + + defer fileToZip.Close() + + // get file info + info, err := fileToZip.Stat() + if err != nil { + return err + } + + header, err := zip.FileInfoHeader(info) + if err != nil { + return err + } + + // Reset original file name + header.Name = file.FileName + + // Change to deflate for better compression + header.Method = zip.Deflate + + writer, err := zipWriter.CreateHeader(header) + if err != nil { + return err + } + + _, err = io.Copy(writer, fileToZip) + + return nil +} diff --git a/watchers/invoices.go b/watchers/invoices.go index 7560e41..79357af 100644 --- a/watchers/invoices.go +++ b/watchers/invoices.go @@ -2,12 +2,10 @@ package watchers import ( "encoding/hex" - "encoding/json" "fmt" "io" "log" "regexp" - "time" "git.sp4ke.com/sp4ke/bit4sat/bus" "git.sp4ke.com/sp4ke/bit4sat/db" @@ -83,51 +81,11 @@ func WatchInvoice() { continue } - // Invoice expired - if expiredInvoice(invoice.CreationDate, invoice.Expiry) { - handleExpiredInvoice(invoice) - } - // Invoice was paid, we handle it handleSettledInvoice(invoice) } } -//TODO -func handleExpiredInvoice(invoice *lnrpc.Invoice) { - - matchUp, err := regexp.MatchString(ReUploadInvoice, invoice.Memo) - if err != nil { - log.Printf("Error regex match: %s", err) - } - - if matchUp { - // Update upload status to "expired" - uploadId, err := storage.GetUploadIdForInvoice(hex.EncodeToString(invoice.RHash)) - if err != nil { - log.Fatal(fmt.Errorf("handleExpiredInvoice: %s", err)) - } - - err = storage.SetUploadStatus(uploadId, storage.UpPayExpired) - if err != nil { - log.Fatal(fmt.Errorf("handleExpiredInvoice %s", err)) - } - } - - // No need to store the invoice - // TODO - // TODO: flush all invoices and uploads - // TODO -} - -func expiredInvoice(creation, expiry int64) bool { - createdAt := time.Unix(int64(creation), 0) - expiresAt := createdAt.Add(time.Second * time.Duration(expiry)) - - return time.Now().After(expiresAt) - -} - func handleSettledInvoice(invoice *lnrpc.Invoice) { // we need to save it and also notify the pubsub channel @@ -140,51 +98,100 @@ func handleSettledInvoice(invoice *lnrpc.Invoice) { log.Printf("Error regex match: %s", err) } + matchDown, err := regexp.MatchString(ReDownInvoice, invoice.Memo) + if err != nil { + log.Printf("Error regex match: %s", err) + } + // Handle upload related invoices if matchUp { // Update upload status to "paid" uploadId, err := storage.GetUploadIdForInvoice(hex.EncodeToString(invoice.RHash)) + log.Printf("watcher: found upload id %s for invoice %s", uploadId, + hex.EncodeToString(invoice.RHash)) if err != nil { - log.Fatal(fmt.Errorf("handleSettledInvoice: %s", err)) + log.Printf("error handleSettledInvoice: %s", err) + return } err = storage.SetUploadStatus(uploadId, storage.UpPaid) if err != nil { - log.Fatal(fmt.Errorf("handleSettledInvoice: %s", err)) + log.Printf("error handleSettledInvoice: %s", err) + return } // Get stored invoice for upload storedInvoice, err := storage.GetUploadInvoice(uploadId) if err != nil { - log.Fatal(fmt.Errorf("handleSettledInvoice: %s", err)) + log.Printf("error handleSettledInvoice: %s", err) + return } + log.Printf("stored invoice %#v", storedInvoice) // Update stored invoice fields newInvoice := ln.UpdateInvoiceFromLnd(storedInvoice, invoice) + log.Printf("new invoice %#v", newInvoice) + // Set invoice for upload err = storage.SetUploadInvoice(uploadId, newInvoice) if err != nil { - log.Fatal(fmt.Errorf("handleSettledInvoice: %s", err)) - } - - newInvoiceJson, err := json.Marshal(newInvoice) - if err != nil { - log.Fatal(fmt.Errorf("handleSettledInvoice: %s", err)) + log.Printf("error handleSettledInvoice: %s", err) + return } - log.Printf("Notifying invoice paid %s", uploadId) + log.Printf("Notifying invoice paid for upload %s", uploadId) // publish invoice was updated to upload_id_paid channel key := fmt.Sprintf("%s:%s", bus.InvoicePaidChannelPrefix, newInvoice.RHash) err = db.DB.Redis.Do(radix.FlatCmd(nil, "PUBLISH", - key, newInvoiceJson)) + key, newInvoice)) + } + + // This is a download invoice + if matchDown { + + // Store the full invoice + key := fmt.Sprintf("invoice_%s", hex.EncodeToString(invoice.RHash)) + storedInvoice := ln.InvoiceFromLndIn(invoice) + err = db.DB.Redis.Do(radix.FlatCmd(nil, "SET", key, storedInvoice)) + if err != nil { + log.Printf("error handleSettledInvoice: %s", err) + return + } + + // Get upload_id related to this invoice + key = fmt.Sprintf("invoice_id_%s_upload_id", storedInvoice.RHash) + log.Printf("looking for %s", key) + var uploadId string + err := db.DB.Redis.Do(radix.FlatCmd(&uploadId, "GET", key)) + if err != nil { + log.Printf("error handleSettledInvoice: %s", err) + return + } + + // Add payment to the corresponding upload_id (user account) + log.Printf("updating payment for upload %s", uploadId) + err = storage.AddPaymentToUpload(uploadId, storedInvoice.RHash, + storedInvoice.Msatoshi) + if err != nil { + log.Printf("error handleSettledInvoice: %s", err) + return + } + + log.Printf("Notifying invoice paid for download") + key = fmt.Sprintf("%s:%s", bus.InvoicePaidChannelPrefix, + storedInvoice.RHash) + + err = db.DB.Redis.Do(radix.FlatCmd(nil, "PUBLISH", + key, storedInvoice)) } if err != nil { - panic(err) + log.Printf("error handleSettledInvoice: %s", err) + return } } diff --git a/web/src/DownloadView.vue b/web/src/DownloadView.vue index db06789..0831de1 100644 --- a/web/src/DownloadView.vue +++ b/web/src/DownloadView.vue @@ -1,9 +1,11 @@ @@ -20,6 +22,8 @@ export default { props: ['dlId'], data(){ return { + dlLink: "if", + showDl: false, error: false, errorMsg: "", } @@ -37,15 +41,39 @@ export default { // ask payment } else if ( res.status === 402) { - res.json() + return res.json() .then((data)=>{ this.$store.commit('setInvoice', data.invoice) this.$store.commit('setFiles', data.files) + + Api.pollInvoice(data.invoice.rhash) + .then((res)=>{ + + // invoice paid we can try again to download + if(res.ok){ + //Api.download(self.dlId) + console.log("calling set download") + self.setDownload() + } + }) + + }) .catch((e)=>{console.log(e)}) + // download + } else { + console.log("calling set download") + self.setDownload() + } }) }, + methods: { + setDownload(){ + this.showDl = true; + this.dlLink = Api.endPoints.download + '/' + this.dlId + } + }, computed: { ...mapState({ diff --git a/web/src/api.js b/web/src/api.js index b7d5b77..3e4a291 100644 --- a/web/src/api.js +++ b/web/src/api.js @@ -7,9 +7,10 @@ const endPoints = { upload: '/api/v1/u', session: '/api/v1/session', - pollstatus: '/api/v1/u/poll', + pollupstatus: '/api/v1/u/poll', checkstatus: '/api/v1/u/check', - download: '/api/v1/d' + download: '/api/v1/d', + pollinvoice: '/api/v1/pollinvoice' } @@ -50,11 +51,21 @@ export async function checkUploadStatus(uploadId){ return fetch(req).catch((e)=>{console.error(e)}) } +export function pollInvoice(invoiceId){ + let req = new Request(endPoints.pollinvoice + '/' + invoiceId,{ + method: 'GET', + credentials: 'same-origin' + }) + + + return fetch(req).catch((e)=>{console.error(e)}) +} + export async function pollUploadStatus(uploadId){ //console.log('polling upload status') - let req = new Request(endPoints.pollstatus + '/' + uploadId,{ + let req = new Request(endPoints.pollupstatus + '/' + uploadId,{ method: 'GET', credentials: 'same-origin' }) @@ -132,4 +143,5 @@ export default { pollUploadStatus: pollUploadStatus, checkUploadStatus: checkUploadStatus, download: download, + pollInvoice: pollInvoice, }