#141: Started file fixing. Added file download handler
This commit is contained in:
@@ -400,7 +400,7 @@ class AppBase:
|
|||||||
|
|
||||||
# Means it's a single item -> continue
|
# Means it's a single item -> continue
|
||||||
if seconditem == "":
|
if seconditem == "":
|
||||||
print("In first - handling %s", seconditem)
|
print("In first - handling %s" % seconditem)
|
||||||
tmpitem = basejson[int(firstitem)]
|
tmpitem = basejson[int(firstitem)]
|
||||||
try:
|
try:
|
||||||
newvalue, is_loop = recurse_json(tmpitem, parsersplit[outercnt+1:])
|
newvalue, is_loop = recurse_json(tmpitem, parsersplit[outercnt+1:])
|
||||||
@@ -884,7 +884,7 @@ class AppBase:
|
|||||||
|
|
||||||
# Custom format for ${name[0,1,2,...]}$
|
# Custom format for ${name[0,1,2,...]}$
|
||||||
#submatch = "([${]{2}([0-9a-zA-Z_-]+)(\[.*\])[}$]{2})"
|
#submatch = "([${]{2}([0-9a-zA-Z_-]+)(\[.*\])[}$]{2})"
|
||||||
submatch = "([${]{2}([0-9a-zA-Z_-]+)(\[.*\])[}$]{2})"
|
submatch = "([${]{2}#?([0-9a-zA-Z_-]+)#?(\[.*\])[}$]{2})"
|
||||||
actualitem = re.findall(submatch, value, re.MULTILINE)
|
actualitem = re.findall(submatch, value, re.MULTILINE)
|
||||||
try:
|
try:
|
||||||
if action["skip_multicheck"]:
|
if action["skip_multicheck"]:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
NAME=app_sdk
|
NAME=app_sdk
|
||||||
VERSION=0.7.5
|
VERSION=0.7.6
|
||||||
|
|
||||||
docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force
|
docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force
|
||||||
docker build . -t frikky/shuffle:$NAME -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION
|
docker build . -t frikky/shuffle:$NAME -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION
|
||||||
|
|||||||
+210
-11
@@ -1790,16 +1790,16 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
|
|||||||
currentOrg = []byte("{}")
|
currentOrg = []byte("{}")
|
||||||
}
|
}
|
||||||
|
|
||||||
returnData := fmt.Sprintf(`
|
returnData := fmt.Sprintf(`{
|
||||||
{
|
"success": true,
|
||||||
"success": true,
|
"username": "%s",
|
||||||
"admin": %s,
|
"admin": %s,
|
||||||
"tutorials": [],
|
"tutorials": [],
|
||||||
"id": "%s",
|
"id": "%s",
|
||||||
"orgs": [%s],
|
"orgs": [%s],
|
||||||
"active_org": %s,
|
"active_org": %s,
|
||||||
"cookies": [{"key": "session_token", "value": "%s", "expiration": %d}]
|
"cookies": [{"key": "session_token", "value": "%s", "expiration": %d}]
|
||||||
}`, parsedAdmin, userInfo.Id, currentOrg, currentOrg, userInfo.Session, expiration.Unix())
|
}`, userInfo.Username, parsedAdmin, userInfo.Id, currentOrg, currentOrg, userInfo.Session, expiration.Unix())
|
||||||
|
|
||||||
resp.WriteHeader(200)
|
resp.WriteHeader(200)
|
||||||
resp.Write([]byte(returnData))
|
resp.Write([]byte(returnData))
|
||||||
@@ -2537,6 +2537,28 @@ func getSession(ctx context.Context, thissession string) (*session, error) {
|
|||||||
return curUser, nil
|
return curUser, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListBooks returns a list of books, ordered by title.
|
||||||
|
func getFile(ctx context.Context, id string) (*File, error) {
|
||||||
|
key := datastore.NameKey("Files", id, nil)
|
||||||
|
curFile := &File{}
|
||||||
|
if err := dbclient.Get(ctx, key, curFile); err != nil {
|
||||||
|
return &File{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return curFile, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setFile(ctx context.Context, file File) error {
|
||||||
|
// clear session_token and API_token for user
|
||||||
|
k := datastore.NameKey("Files", file.Id, nil)
|
||||||
|
if _, err := dbclient.Put(ctx, k, &file); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ListBooks returns a list of books, ordered by title.
|
// ListBooks returns a list of books, ordered by title.
|
||||||
func getOrg(ctx context.Context, id string) (*Org, error) {
|
func getOrg(ctx context.Context, id string) (*Org, error) {
|
||||||
key := datastore.NameKey("Organizations", id, nil)
|
key := datastore.NameKey("Organizations", id, nil)
|
||||||
@@ -6648,6 +6670,38 @@ func runInit(ctx context.Context) {
|
|||||||
log.Printf("Set workflow orgs for %d workflows", updated)
|
log.Printf("Set workflow orgs for %d workflows", updated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileq := datastore.NewQuery("Files").Limit(1)
|
||||||
|
count, err := dbclient.Count(ctx, fileq)
|
||||||
|
|
||||||
|
if err == nil && count == 0 {
|
||||||
|
basepath := "."
|
||||||
|
filename := "testfile.txt"
|
||||||
|
fileId := uuid.NewV4().String()
|
||||||
|
log.Printf("Creating new file reference %s because none exist!", fileId)
|
||||||
|
workflowId := "2e9d6474-402c-4dcc-bb53-45f638ca18d3"
|
||||||
|
downloadPath := fmt.Sprintf("%s/%s/%s/%s", basepath, activeOrgs[0].Id, workflowId, fileId)
|
||||||
|
|
||||||
|
timeNow := time.Now().Unix()
|
||||||
|
newFile := File{
|
||||||
|
Id: fileId,
|
||||||
|
CreatedAt: timeNow,
|
||||||
|
UpdatedAt: timeNow,
|
||||||
|
Description: "Created by system for testing",
|
||||||
|
Status: "active",
|
||||||
|
Filename: filename,
|
||||||
|
OrgId: activeOrgs[0].Id,
|
||||||
|
WorkflowId: workflowId,
|
||||||
|
DownloadPath: downloadPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setFile(ctx, newFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed setting file: %s", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("Created file %s in init", newFile.DownloadPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets schedules and starts them
|
// Gets schedules and starts them
|
||||||
@@ -7183,6 +7237,141 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) {
|
|||||||
resp.Write(respBody)
|
resp.Write(respBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type File struct {
|
||||||
|
Id string `json:"id" datastore:"id"`
|
||||||
|
Type string `json:"type" datastore:"type"`
|
||||||
|
CreatedAt int64 `json:"created_at" datastore:"created_at"`
|
||||||
|
UpdatedAt int64 `json:"updated_at" datastore:"updated_at"`
|
||||||
|
CreatedBy struct {
|
||||||
|
ID int `json:"id" datastore:"id"`
|
||||||
|
Type string `json:"type" datastore:"type"`
|
||||||
|
Login string `json:"login" datastore:"login"`
|
||||||
|
Name string `json:"name" datastore:"name"`
|
||||||
|
} `json:"created_by" datastore:"created_by"`
|
||||||
|
Description string `json:"description" datastore:"description"`
|
||||||
|
Etag int `json:"etag" datastore:"etag"`
|
||||||
|
ExpiresAt string `json:"expires_at" datastore:"expires_at"`
|
||||||
|
Folder struct {
|
||||||
|
ID int `json:"id" datastore:"id"`
|
||||||
|
Type string `json:"type" datastore:"type"`
|
||||||
|
Etag int `json:"etag" datastore:"etag"`
|
||||||
|
Name string `json:"name" datastore:"name"`
|
||||||
|
SequenceID int `json:"sequence_id" datastore:"sequence_id"`
|
||||||
|
} `json:"folder" datastore:"folder"`
|
||||||
|
Status string `json:"status" datastore:"status"`
|
||||||
|
Filename string `json:"filename" datastore:"filename"`
|
||||||
|
UpdatedBy struct {
|
||||||
|
ID int `json:"id" datastore:"id"`
|
||||||
|
Type string `json:"type" datastore:"type"`
|
||||||
|
Login string `json:"login" datastore:"login"`
|
||||||
|
Name string `json:"name" datastore:"name"`
|
||||||
|
} `json:"updated_by" datastore:"updated_by"`
|
||||||
|
URL string `json:"url" datastore:"org"`
|
||||||
|
OrgId string `json:"org_id" datastore:"org_id"`
|
||||||
|
WorkflowId string `json:"workflow_id" datastore:"workflow_id"`
|
||||||
|
Workflows []string `json:"workflows" datastore:"workflows"`
|
||||||
|
DownloadPath string `json:"download_path" datastore:"download_path"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleGetFileContent(resp http.ResponseWriter, request *http.Request) {
|
||||||
|
cors := handleCors(resp, request)
|
||||||
|
if cors {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileId string
|
||||||
|
location := strings.Split(request.URL.String(), "/")
|
||||||
|
if location[1] == "api" {
|
||||||
|
if len(location) <= 4 {
|
||||||
|
log.Printf("Path too short: %d", len(location))
|
||||||
|
resp.WriteHeader(401)
|
||||||
|
resp.Write([]byte(`{"success": false}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fileId = location[4]
|
||||||
|
}
|
||||||
|
|
||||||
|
//log.Printf("In file download")
|
||||||
|
user, err := handleApiAuthentication(resp, request)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Api authentication failed in file download: %s", err)
|
||||||
|
resp.WriteHeader(401)
|
||||||
|
resp.Write([]byte(`{"success": false}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Verify if the user has access to the file: org_id and workflow
|
||||||
|
|
||||||
|
log.Printf("Should get file %s", fileId)
|
||||||
|
ctx := context.Background()
|
||||||
|
file, err := getFile(ctx, fileId)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("File %s not found: %s", fileId, err)
|
||||||
|
resp.WriteHeader(401)
|
||||||
|
resp.Write([]byte(`{"success": false}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
found := false
|
||||||
|
if file.OrgId == user.ActiveOrg.Id {
|
||||||
|
found = true
|
||||||
|
} else {
|
||||||
|
for _, item := range user.Orgs {
|
||||||
|
if item == file.OrgId {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
log.Printf("User %s doesn't have access to %s", user.Username, fileId)
|
||||||
|
resp.WriteHeader(401)
|
||||||
|
resp.Write([]byte(`{"success": false}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixme: More auth: org and workflow!
|
||||||
|
downloadPath := file.DownloadPath
|
||||||
|
log.Printf("Downloadpath: %s", downloadPath)
|
||||||
|
Openfile, err := os.Open(downloadPath)
|
||||||
|
defer Openfile.Close() //Close after function return
|
||||||
|
if err != nil {
|
||||||
|
//File not found, send 404
|
||||||
|
http.Error(resp, "File not found.", 404)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//File is found, create and send the correct headers
|
||||||
|
//Get the Content-Type of the file
|
||||||
|
//Create a buffer to store the header of the file in
|
||||||
|
FileHeader := make([]byte, 512)
|
||||||
|
//Copy the headers into the FileHeader buffer
|
||||||
|
Openfile.Read(FileHeader)
|
||||||
|
//Get content type of file
|
||||||
|
FileContentType := http.DetectContentType(FileHeader)
|
||||||
|
|
||||||
|
//Get the file size
|
||||||
|
FileStat, _ := Openfile.Stat() //Get info from file
|
||||||
|
FileSize := strconv.FormatInt(FileStat.Size(), 10) //Get file size as a string
|
||||||
|
|
||||||
|
//Send the headers
|
||||||
|
resp.Header().Set("Content-Disposition", "attachment; filename="+fileId)
|
||||||
|
resp.Header().Set("Content-Type", FileContentType)
|
||||||
|
resp.Header().Set("Content-Length", FileSize)
|
||||||
|
|
||||||
|
//Send the file
|
||||||
|
//We read 512 bytes from the file already, so we reset the offset back to 0
|
||||||
|
Openfile.Seek(0, 0)
|
||||||
|
io.Copy(resp, Openfile) //'Copy' the file to the client
|
||||||
|
return
|
||||||
|
|
||||||
|
//log.Printf("Should download file %s", downloadPath)
|
||||||
|
//resp.WriteHeader(200)
|
||||||
|
//resp.Write([]byte("OK"))
|
||||||
|
}
|
||||||
|
|
||||||
func initHandlers() {
|
func initHandlers() {
|
||||||
var err error
|
var err error
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@@ -7302,7 +7491,17 @@ func initHandlers() {
|
|||||||
|
|
||||||
// NEW for 0.8.0
|
// NEW for 0.8.0
|
||||||
r.HandleFunc("/api/v1/cloud/setup", handleCloudSetup).Methods("POST", "OPTIONS")
|
r.HandleFunc("/api/v1/cloud/setup", handleCloudSetup).Methods("POST", "OPTIONS")
|
||||||
r.HandleFunc("/api/v1/getorgs", handleGetOrgs).Methods("GET", "OPTIONS")
|
r.HandleFunc("/api/v1/orgs", handleGetOrgs).Methods("GET", "OPTIONS")
|
||||||
|
|
||||||
|
// Important for email, IDS etc. Create this by:
|
||||||
|
// PS: For cloud, this has to use cloud storage.
|
||||||
|
// https://developer.box.com/reference/get-files-id-content/
|
||||||
|
// 1. Creating the "get file" option. Make it possible to run this in the frontend.
|
||||||
|
r.HandleFunc("/api/v1/files/{fileId}/content", handleGetFileContent).Methods("GET", "OPTIONS")
|
||||||
|
//r.HandleFunc("/api/v1/files/create", handleGetFile).Methods("POST", "OPTIONS")
|
||||||
|
//r.HandleFunc("/api/v1/files/upload", handleGetFile).Methods("POST", "OPTIONS")
|
||||||
|
//r.HandleFunc("/api/v1/files/{fileId}", handleGetFile).Methods("GET", "OPTIONS")
|
||||||
|
//r.HandleFunc("/api/v1/files/{fileId}", handleGetFile).Methods("DELETE", "OPTIONS")
|
||||||
|
|
||||||
http.Handle("/", r)
|
http.Handle("/", r)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# ./b199646b-16d2-456d-9fd6-b9972e929466/2e9d6474-402c-4dcc-bb53-45f638ca18d3/0d676d72-5d53-4803-a6b0-4afb464df828
|
||||||
|
# org_id / workflow_id / file_id
|
||||||
|
curl http://192.168.3.6:5001/api/v1/files/0d676d72-5d53-4803-a6b0-4afb464df828/content -H "Authorization: Bearer 093b576f-19ea-4353-b685-362ab50f39f4"
|
||||||
@@ -35,7 +35,7 @@ const Header = props => {
|
|||||||
|
|
||||||
// DEBUG HERE
|
// DEBUG HERE
|
||||||
const handleClickLogout = () => {
|
const handleClickLogout = () => {
|
||||||
console.log("SHOULD LOG OUT")
|
console.log("SHOULD LOG OUT")
|
||||||
console.log(isLoggedIn)
|
console.log(isLoggedIn)
|
||||||
|
|
||||||
// Don't really care about the logout
|
// Don't really care about the logout
|
||||||
@@ -47,10 +47,9 @@ const Header = props => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// Log out anyway
|
// Log out anyway
|
||||||
console.log("Hey")
|
removeCookie("session_token", {path: "/"})
|
||||||
removeCookie("session_token", {path: "/"})
|
//window.location.pathname = "/"
|
||||||
window.location.pathname = "/"
|
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
@@ -158,6 +157,16 @@ const Header = props => {
|
|||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
{/*
|
||||||
|
<ListItem style={{textAlign: "center"}}>
|
||||||
|
<Link to="/pricing" style={hrefStyle}>
|
||||||
|
<div onMouseOver={handleDocsHover} onMouseOut={handleDocsHoverOut} style={{color: DocsHoverColor, cursor: "pointer", display: "flex"}}>
|
||||||
|
<DescriptionIcon style={{marginRight: "5px"}} />
|
||||||
|
<span style={{marginTop: 2}}>Pricing</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</ListItem>
|
||||||
|
*/}
|
||||||
{/*
|
{/*
|
||||||
<ListItem style={{textAlign: "center"}}>
|
<ListItem style={{textAlign: "center"}}>
|
||||||
<Link to="/configurations" style={hrefStyle}>
|
<Link to="/configurations" style={hrefStyle}>
|
||||||
@@ -183,6 +192,19 @@ const Header = props => {
|
|||||||
color="primary"> Settings</Button>
|
color="primary"> Settings</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
{/*
|
||||||
|
<ListItem>
|
||||||
|
<Link to="/contact" style={hrefStyle}>
|
||||||
|
<Button
|
||||||
|
style={{}}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
Contact
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</ListItem>
|
||||||
|
*/}
|
||||||
{userdata === undefined || userdata.admin === undefined || userdata.admin === null || !userdata.admin ? null :
|
{userdata === undefined || userdata.admin === undefined || userdata.admin === null || !userdata.admin ? null :
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<Link to="/admin" style={hrefStyle}>
|
<Link to="/admin" style={hrefStyle}>
|
||||||
@@ -299,8 +321,8 @@ const Header = props => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
// <Divider style={{height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
|
// <Divider style={{height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
|
||||||
const loadedCheck = isLoaded ?
|
const loadedCheck =
|
||||||
<div>
|
<div style={{minHeight: 68}}>
|
||||||
<BrowserView>
|
<BrowserView>
|
||||||
{loginTextBrowser}
|
{loginTextBrowser}
|
||||||
</BrowserView>
|
</BrowserView>
|
||||||
@@ -308,10 +330,6 @@ const Header = props => {
|
|||||||
{loginTextMobile}
|
{loginTextMobile}
|
||||||
</MobileView>
|
</MobileView>
|
||||||
</div>
|
</div>
|
||||||
:
|
|
||||||
<div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
// <div style={{backgroundImage: "linear-gradient(-90deg,#342f78 0,#29255e 50%,#1b1947 100%"}}>
|
// <div style={{backgroundImage: "linear-gradient(-90deg,#342f78 0,#29255e 50%,#1b1947 100%"}}>
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -555,7 +555,7 @@ const Admin = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getOrgs = () => {
|
const getOrgs = () => {
|
||||||
fetch(globalUrl + "/api/v1/getorgs", {
|
fetch(globalUrl + "/api/v1/orgs", {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|||||||
@@ -109,13 +109,13 @@ const Settings = (props) => {
|
|||||||
|
|
||||||
const getSettings = () => {
|
const getSettings = () => {
|
||||||
fetch(globalUrl+"/api/v1/getsettings", {
|
fetch(globalUrl+"/api/v1/getsettings", {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
},
|
},
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
console.log("Status not 200 for WORKFLOW EXECUTION :O!")
|
console.log("Status not 200 for WORKFLOW EXECUTION :O!")
|
||||||
@@ -137,24 +137,24 @@ const Settings = (props) => {
|
|||||||
if (userInfo.username.length > 0) {
|
if (userInfo.username.length > 0) {
|
||||||
setUsername(userInfo.username)
|
setUsername(userInfo.username)
|
||||||
}
|
}
|
||||||
if (userInfo.firstname.length > 0) {
|
//if (userInfo.firstname.length > 0) {
|
||||||
setFirstname(userInfo.firstname)
|
// setFirstname(userInfo.firstname)
|
||||||
}
|
//}
|
||||||
if (userInfo.lastname.length > 0) {
|
//if (userInfo.lastname.length > 0) {
|
||||||
setLastname(userInfo.lastname)
|
// setLastname(userInfo.lastname)
|
||||||
}
|
//}
|
||||||
if (userInfo.title.length > 0) {
|
//if (userInfo.title.length > 0) {
|
||||||
setTitle(userInfo.title)
|
// setTitle(userInfo.title)
|
||||||
}
|
//}
|
||||||
if (userInfo.companyname.length > 0) {
|
//if (userInfo.companyname.length > 0) {
|
||||||
setCompanyname(userInfo.companyname)
|
// setCompanyname(userInfo.companyname)
|
||||||
}
|
//}
|
||||||
if (userInfo.phone.length > 0) {
|
//if (userInfo.phone.length > 0) {
|
||||||
setPhone(userInfo.phone)
|
// setPhone(userInfo.phone)
|
||||||
}
|
//}
|
||||||
if (userInfo.email.length > 0) {
|
//if (userInfo.email.length > 0) {
|
||||||
setEmail(userInfo.email)
|
// setEmail(userInfo.email)
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ const Settings = (props) => {
|
|||||||
<div style={{display: "flex", marginTop: "80px"}}>
|
<div style={{display: "flex", marginTop: "80px"}}>
|
||||||
<Paper style={boxStyle}>
|
<Paper style={boxStyle}>
|
||||||
<h2>APIKEY</h2>
|
<h2>APIKEY</h2>
|
||||||
<Link to="/docs/API#authentication" style={{textDecoration: "none", color: "#f85a3e"}}>What is the API key used for?</Link>
|
<a target="_blank" href="/docs/API#authentication" style={{textDecoration: "none", color: "#f85a3e"}}>What is the API key used for?</a>
|
||||||
<TextField
|
<TextField
|
||||||
style={{backgroundColor: theme.palette.inputColor, flex: "1"}}
|
style={{backgroundColor: theme.palette.inputColor, flex: "1"}}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
|
|||||||
Reference in New Issue
Block a user