Compare commits
2 Commits
b0a81780dc
...
55bec8e5f8
Author | SHA1 | Date |
---|---|---|
Tracker-Friendly | 55bec8e5f8 | |
Tracker-Friendly | 3b70fe7b4b |
87
APIDOCS.md
87
APIDOCS.md
|
@ -3,49 +3,86 @@ Use the Burgernotes API to automate tasks, build your own client, and more!
|
||||||
|
|
||||||
Headers should be: "Content-type: application/json; charset=UTF-8" for all POSTs
|
Headers should be: "Content-type: application/json; charset=UTF-8" for all POSTs
|
||||||
|
|
||||||
## 🔑 Authentication (version 1)
|
## 🔑 Authentication
|
||||||
|
|
||||||
POST - /api/signup - provide "username" and "password".
|
POST - /api/signup - provide "username" and "password".
|
||||||
|
|
||||||
POST - /api/login - provide "username", "password" and "newpass"
|
POST - /api/login - provide "username" and "password"
|
||||||
|
|
||||||
To prevent the server from knowing the encryption key, the password you provide in the request must be hashed with the SHA-3 algorithm with 128 iterations (the hash is hashed again 128 times).
|
To prevent the server from knowing the encryption key, the password you provide in the request must be hashed with Argon2ID as per the following parameters:
|
||||||
|
|
||||||
|
- salt: UTF-8 Representation of "I munch Burgers!!" (should be 16 bytes),
|
||||||
|
- parallelism: 1
|
||||||
|
- iterations: 32
|
||||||
|
- memorySize: 19264 bytes
|
||||||
|
- hashLength: 32
|
||||||
|
- outputType: hexadecimal
|
||||||
|
|
||||||
Password should be at least 8 characters, username must be under 20 characters and alphanumeric.
|
Password should be at least 8 characters, username must be under 20 characters and alphanumeric.
|
||||||
|
|
||||||
Newpass is a more direct call to /api/changepassword that is deprecated in version 2. Set newpass to a value of "no" in order to identify as a version 1 api and not trigger the backwards compatibility layer.
|
|
||||||
|
|
||||||
If username is taken, error code 422 will return.
|
If username is taken, error code 422 will return.
|
||||||
|
|
||||||
Assuming everything went correctly, the server will return a secret key.
|
Assuming everything went correctly, the server will return a secret key.
|
||||||
|
|
||||||
You'll need to store two things in local storage:
|
You'll need to store two things in local storage:
|
||||||
- The secret key you just got, used to fetch notes, save stuff etc.
|
- The secret key you just got, used to fetch notes, save stuff etc.
|
||||||
- A SHA512 hashed password, used as encryption key
|
- Another password, which is hashed the same way, but with a salt of "I love Burgernotes!" (again, UTF-8 representation, 16 bytes).
|
||||||
|
|
||||||
### Additional notes on version 2
|
If you are using the OAuth2 flow (totally optional, I know it's really complex) then you should also store the login password to use later, or put the OAuth2 logic straight after this.
|
||||||
|
|
||||||
For version two, /api/signup and /api/login require the legacyPassword API, to allow for backwards compatibility up to version 0. To do this, set the header "X-Burgernotes-Version" to the current version number without any dots (E.G 2.1.4 -> 214).
|
## 🌐 OAuth2 + Burgerauth
|
||||||
|
|
||||||
During signup, "legacyPassword" should also be provided. legacyPassword should be the SHA-3 128 iteration hash of the Argon2ID hash of the password following these settings (yes, hashing a hash):
|
For security purposes, traditional OAuth2 is not supported. Instead, we use Burgerauth, a custom OAuth2 implementation that provides a unique-yet-consistent "authentication code" for each user. It is created in a special way as to not involve the server, meaning the security of Burgernotes is not compromised by using OAuth2, which is normally a very server-side process.
|
||||||
|
|
||||||
|
### How it works
|
||||||
|
First, perform regular client-side OAuth2 authentication using Burgerauth, as detailed in its [own documentation](https://concord.hectabit.org/HectaBit/burgerauth/src/branch/main/APIDOCS.md). Once regular OAuth2 is complete, you will be given an authentication code, which is important for the next step.
|
||||||
|
|
||||||
|
You now have one of two options:
|
||||||
|
1. If your app is based on the web, you can host a static page provided [here](https://concord.hectabit.org/HectaBit/burgerauth/src/branch/main/keyExchangeRdir.html) on any static service. Redirect to this page with the OAuth2 token stored in localStorage as BURGERAUTH-RDIR-TOKEN. The page will then communicate with a corresponding page on Burgerauth, and transmit the key securely via RSA. You may see the page redirect a couple of times as it communicates the infomation across. All you need to know is that once it is finished, it will redirect back to the page that redirected to it with the key in localStorage as DONOTSHARE-EXCHANGED-KEY.
|
||||||
|
2. If your app is not web-based, you can open up a webview to [here](https://auth.hectabit.org/keyexchangeclient). Once it is finished, it will send a postMessage with the body "finished" to the target "*" and output "finished" to the JavaScript console. The key will be in localStorage as DONOTSHARE-EXCHANGED-KEY.
|
||||||
|
3. Alternatively, you can host a local webserver and host the aforementioned page on it. It will work the same way as the first option, and once it is finished, it will detect that it was not redirected to and instead will set it as a cookie expiring in 5 minutes and then refresh the page. You should detect for the cookie and use its value, and then kill the webserver. This method is not recommended because of its complexity and overhead.
|
||||||
|
|
||||||
|
Once this is finished, you should check if there is an existing OAuth2 entry on the server like this:
|
||||||
|
|
||||||
|
POST - /api/oauth/get - provide "username" and "oauthProvider"
|
||||||
|
oauthProvider is the name of the OAuth2 provider, such as "burgerauth" or "google" (google is used as an example, they do not use the burgerauth extensions and are therefore incompatible).
|
||||||
|
It does not have to be the actual name, but it has to be unique to the provider (per user). The sub given by OpenID Connect is a good choice.
|
||||||
|
|
||||||
|
### 404 is returned
|
||||||
|
No entry has been found, and you have to log in the user as normal.
|
||||||
|
Once this is done, you should create an entry like this:
|
||||||
|
|
||||||
|
POST - /api/oauth/new - provide "secretKey", "oauthProvider" and "encryptedPassword"
|
||||||
|
|
||||||
|
To create encryptedPassword, follow these steps:
|
||||||
|
|
||||||
|
1. Generate a random 16-byte IV.
|
||||||
|
2. Create a JSON structure like this:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"loginPass": "(the SHA-3 password hash created in the login process)",
|
||||||
|
"cryptoPass": "(the SHA-512 password hash stored in localStorage)"
|
||||||
|
}
|
||||||
```
|
```
|
||||||
Parallelism should be 1
|
3. Convert the JSON to a string and then encrypt it using AES-256 GCM using the exchangeKey as the key and the IV created earlier as the IV.
|
||||||
|
4. Create a JSON structure like this:
|
||||||
Iterations should be 256
|
```json
|
||||||
|
{
|
||||||
Memory Allocated in bytes should be 512
|
"iv": "(the IV)",
|
||||||
|
"content": "(the encrypted JSON)"
|
||||||
Length of Hash should be 32 bytes
|
}
|
||||||
|
|
||||||
The output should be in the encoded format, not the hashed format
|
|
||||||
|
|
||||||
Salt should be the SHA512 of the password
|
|
||||||
```
|
```
|
||||||
|
5. Finally, convert the JSON into a string, base64 encode it, and send it off as encryptedPassword.
|
||||||
|
|
||||||
On login, as well as the key, the server may return "legacyPasswordNeeded" = true.
|
Do not store the exchangeKey after this point, as it is no longer needed.
|
||||||
|
|
||||||
If this is the case, POST /api/v2/addlegacypassword (with the aforementioned header), provide "secretKey" and "legacyPassword" (hashed the same way as signup).
|
### 200 is returned
|
||||||
|
An entry exists, and encryptedPassword has been returned using JSON.
|
||||||
|
encryptedPassword is the password encrypted using AES-256 GCM, and the IV is included in the JSON, in this format defined above.
|
||||||
|
|
||||||
|
Use the passwords defined in the JSON structure before the last one to log in normally.
|
||||||
|
|
||||||
|
#### Finally, you are done!
|
||||||
|
|
||||||
## 🔐 Encryption
|
## 🔐 Encryption
|
||||||
|
|
||||||
|
@ -61,13 +98,13 @@ POST - /api/listnotes - list notes, provide "secretKey"
|
||||||
note titles will have to be decrypted.
|
note titles will have to be decrypted.
|
||||||
|
|
||||||
POST - /api/newnote - create a note, provide "secretKey" and "noteName"
|
POST - /api/newnote - create a note, provide "secretKey" and "noteName"
|
||||||
"noteName" should be encrypted.
|
"noteName" should be encrypted using AES-256 GCM with the DONOTSHARE-password as the key and a random 16-byte IV.
|
||||||
|
|
||||||
POST - /api/readnote - read notes, provide "secretKey" and "noteId"
|
POST - /api/readnote - read notes, provide "secretKey" and "noteId"
|
||||||
note content will have to be decrypted.
|
note content will have to be decrypted.
|
||||||
|
|
||||||
POST - /api/editnote - edit notes, provide "secretKey", "noteId", "title", and "content"
|
POST - /api/editnote - edit notes, provide "secretKey", "noteId", "title", and "content"
|
||||||
"content" should be encrypted.
|
"content" should be encrypted using AES-256 GCM with the DONOTSHARE-password as the key and a random 16-byte IV.
|
||||||
"title" is the first line of the note content, and should be encrypted.
|
"title" is the first line of the note content, and should be encrypted.
|
||||||
|
|
||||||
POST - /api/removenote - remove notes, provide "secretKey" and "noteId"
|
POST - /api/removenote - remove notes, provide "secretKey" and "noteId"
|
||||||
|
@ -87,7 +124,7 @@ POST - /api/exportnotes - export notes, provide "secretKey"
|
||||||
note content and title will have to be decrypted
|
note content and title will have to be decrypted
|
||||||
|
|
||||||
POST - /api/importnotes - import notes, provide "secretKey" and "notes"
|
POST - /api/importnotes - import notes, provide "secretKey" and "notes"
|
||||||
note content should be encrypted and follow the /api/exportnotes format, in a marshalled json string
|
note content and title should be encrypted using AES-256 GCM with the DONOTSHARE-password as the key and a random 16-byte IV and follow the /api/exportnotes format, in a marshalled json string
|
||||||
|
|
||||||
POST - /api/sessions/list - show all sessions, provide "secretKey"
|
POST - /api/sessions/list - show all sessions, provide "secretKey"
|
||||||
|
|
||||||
|
|
373
main.go
373
main.go
|
@ -17,10 +17,9 @@ import (
|
||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-contrib/sessions/cookie"
|
"github.com/gin-contrib/sessions/cookie"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
"github.com/mattn/go-sqlite3"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"golang.org/x/crypto/scrypt"
|
"golang.org/x/crypto/scrypt"
|
||||||
"golang.org/x/crypto/sha3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -32,16 +31,15 @@ var (
|
||||||
saltChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
saltChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
)
|
)
|
||||||
|
|
||||||
func genSalt(length int) (string, error) {
|
func randomChars(length int) (string, error) {
|
||||||
if length <= 0 {
|
if length <= 0 {
|
||||||
log.Println("[ERROR] Known in genSalt() at", strconv.FormatInt(time.Now().Unix(), 10)+":", "Salt length must be at least one.")
|
return "", errors.New("salt length must be at least one")
|
||||||
}
|
}
|
||||||
|
|
||||||
salt := make([]byte, length)
|
salt := make([]byte, length)
|
||||||
randomBytes := make([]byte, length)
|
randomBytes := make([]byte, length)
|
||||||
_, err := rand.Read(randomBytes)
|
_, err := rand.Read(randomBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in genSalt() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,24 +49,12 @@ func genSalt(length int) (string, error) {
|
||||||
return string(salt), nil
|
return string(salt), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func hashSha3(iterations int, input string) string {
|
|
||||||
key := input
|
|
||||||
for i := 0; i < iterations; i++ {
|
|
||||||
hash := sha3.New512()
|
|
||||||
hash.Write([]byte(key))
|
|
||||||
keyBytes := hash.Sum(nil)
|
|
||||||
key = hex.EncodeToString(keyBytes)
|
|
||||||
}
|
|
||||||
return key
|
|
||||||
}
|
|
||||||
|
|
||||||
func hash(password, salt string) (string, error) {
|
func hash(password, salt string) (string, error) {
|
||||||
passwordBytes := []byte(password)
|
passwordBytes := []byte(password)
|
||||||
saltBytes := []byte(salt)
|
saltBytes := []byte(salt)
|
||||||
|
|
||||||
derivedKey, err := scrypt.Key(passwordBytes, saltBytes, 32768, 8, 1, 64)
|
derivedKey, err := scrypt.Key(passwordBytes, saltBytes, 32768, 8, 1, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in hash() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,19 +168,19 @@ func initDb() {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
err = generateDB()
|
err = generateDB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("[FATAL] Unknown while generating database at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Fatalln("[FATAL] Unknown while generating database:", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Print("[PROMPT] Proceeding will overwrite the database. Proceed? (y/n): ")
|
log.Print("[PROMPT] Proceeding will overwrite the database. Proceed? (y/n): ")
|
||||||
var answer string
|
var answer string
|
||||||
_, err := fmt.Scanln(&answer)
|
_, err := fmt.Scanln(&answer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("[FATAL] Unknown while scanning input at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Fatalln("[FATAL] Unknown while scanning input:", err)
|
||||||
}
|
}
|
||||||
if strings.ToLower(answer) == "y" {
|
if strings.ToLower(answer) == "y" {
|
||||||
err := generateDB()
|
err := generateDB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("[FATAL] Unknown while generating database at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Fatalln("[FATAL] Unknown while generating database:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if answer == ":3" {
|
} else if answer == ":3" {
|
||||||
|
@ -210,21 +196,23 @@ func migrateDb() {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
err = generateDB()
|
err = generateDB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("[FATAL] Unknown while generating database at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Fatalln("[FATAL] Unknown while generating database:", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Println("[PROMPT] Proceeding will render the database unusable for older versions of Burgernotes. Proceed? (y/n): ")
|
log.Println("[PROMPT] Proceeding will render the database unusable for older versions of Burgernotes. Proceed? (y/n): ")
|
||||||
var answer string
|
var answer string
|
||||||
_, err := fmt.Scanln(&answer)
|
_, err := fmt.Scanln(&answer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("[FATAL] Unknown while scanning input at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Fatalln("[FATAL] Unknown while scanning input:", err)
|
||||||
}
|
}
|
||||||
if strings.ToLower(answer) == "y" {
|
if strings.ToLower(answer) == "y" {
|
||||||
_, err := conn.Exec("ALTER TABLE users ADD COLUMN versionTwoLegacyPassword TEXT NOT NULL DEFAULT 'nil'")
|
_, err = conn.Exec("ALTER TABLE users DROP COLUMN versionTwoLegacyPassword")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("[FATAL] Unknown while migrating database at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[WARN] Unknown while migrating database (1/2):", err)
|
||||||
|
log.Println("[INFO] This is likely because your database is already migrated. This is not a problem, and Burgernotes does not need this removed - it is just for cleanup")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
_, err = conn.Exec("CREATE TABLE oauth (id INTEGER NOT NULL, oauthProvider TEXT NOT NULL, encryptedPasswd TEXT NOT NULL)")
|
||||||
} else if answer == ":3" {
|
} else if answer == ":3" {
|
||||||
log.Println("[:3] :3")
|
log.Println("[:3] :3")
|
||||||
} else {
|
} else {
|
||||||
|
@ -248,7 +236,7 @@ func main() {
|
||||||
|
|
||||||
err := viper.ReadInConfig()
|
err := viper.ReadInConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("[FATAL] Error in config file at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Fatalln("[FATAL] Error in config file:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
host = viper.GetString("config.HOST")
|
host = viper.GetString("config.HOST")
|
||||||
|
@ -276,12 +264,12 @@ func main() {
|
||||||
|
|
||||||
conn, err = sql.Open("sqlite3", "database.db")
|
conn, err = sql.Open("sqlite3", "database.db")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("[FATAL] Cannot open database at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Fatalln("[FATAL] Cannot open database:", err)
|
||||||
}
|
}
|
||||||
defer func(conn *sql.DB) {
|
defer func(conn *sql.DB) {
|
||||||
err := conn.Close()
|
err := conn.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in main() defer at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in main() defer:", err)
|
||||||
}
|
}
|
||||||
}(conn)
|
}(conn)
|
||||||
|
|
||||||
|
@ -314,11 +302,11 @@ func main() {
|
||||||
})
|
})
|
||||||
|
|
||||||
router.GET("/api/version", func(c *gin.Context) {
|
router.GET("/api/version", func(c *gin.Context) {
|
||||||
c.String(200, "Burgernotes Version 2.0 Beta 1")
|
c.String(200, "Burgernotes Version 2.0 Beta 2")
|
||||||
})
|
})
|
||||||
|
|
||||||
router.GET("/api/versionjson", func(c *gin.Context) {
|
router.GET("/api/versionjson", func(c *gin.Context) {
|
||||||
c.JSON(200, gin.H{"name": "Burgernotes", "versiontxt": "Version 2.0 Beta 1", "versionsem": "2.0.0b1", "versionnum": "200"})
|
c.JSON(200, gin.H{"name": "Burgernotes", "versiontxt": "Version 2.0 Beta 2", "versionsem": "2.0.0b2", "versionnum": "200"})
|
||||||
})
|
})
|
||||||
|
|
||||||
router.POST("/api/signup", func(c *gin.Context) {
|
router.POST("/api/signup", func(c *gin.Context) {
|
||||||
|
@ -340,20 +328,6 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
enableAPIVersion2 := false
|
|
||||||
versionCheck := c.GetHeader("X-Burgernotes-Version")
|
|
||||||
if versionCheck != "" {
|
|
||||||
versionCheckInt, err := strconv.Atoi(versionCheck)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("[ERROR] Unknown in /api/signup versionCheck at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-VERSIONCHECK"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if versionCheckInt > 199 {
|
|
||||||
enableAPIVersion2 = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if username == "" || password == "" || len(username) > 20 || !regexp.MustCompile("^[a-zA-Z0-9]+$").MatchString(username) {
|
if username == "" || password == "" || len(username) > 20 || !regexp.MustCompile("^[a-zA-Z0-9]+$").MatchString(username) {
|
||||||
c.JSON(422, gin.H{"error": "Invalid username or password"})
|
c.JSON(422, gin.H{"error": "Invalid username or password"})
|
||||||
return
|
return
|
||||||
|
@ -361,7 +335,7 @@ func main() {
|
||||||
|
|
||||||
_, taken, err := checkUsernameTaken(username)
|
_, taken, err := checkUsernameTaken(username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/signup checkUsernameTaken() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/signup checkUsernameTaken():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-USERTAKEN"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-USERTAKEN"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -370,44 +344,22 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
salt, err := genSalt(16)
|
salt, err := randomChars(16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/signup genSalt() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/signup randomChars():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-SALT"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-SALT"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hashedPasswd, err := hash(password, salt)
|
hashedPasswd, err := hash(password, salt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/signup hash() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/signup hash():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-HASH"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-HASH"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !enableAPIVersion2 {
|
_, err = conn.Exec("INSERT INTO users (username, password, created) VALUES (?, ?, ?)", username, hashedPasswd, strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
_, err = conn.Exec("INSERT INTO users (username, password, versionTwoLegacyPassword, created) VALUES (?, ?, ?, ?)", username, hashedPasswd, "nil", strconv.FormatInt(time.Now().Unix(), 10))
|
|
||||||
} else {
|
|
||||||
legacyPassword, ok := data["legacyPassword"].(string)
|
|
||||||
if !ok {
|
|
||||||
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
salt, err := genSalt(16)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/signup genSalt() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/signup Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-SALT"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
legacyPasswordHash, err := hash(legacyPassword, salt)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("[ERROR] Unknown in /api/signup hash() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-HASH"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, err = conn.Exec("INSERT INTO users (username, password, versionTwoLegacyPassword, created) VALUES (?, ?, ?, ?)", username, hashedPasswd, legacyPasswordHash, strconv.FormatInt(time.Now().Unix(), 10))
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Println("[ERROR] Unknown in /api/signup Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-DBINSERT"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-DBINSERT"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -421,15 +373,15 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := genSalt(512)
|
token, err := randomChars(512)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/signup token genSalt() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/signup token randomChars():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-SESSIONSALT"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-SESSIONSALT"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = conn.Exec("INSERT INTO sessions (session, id, device) VALUES (?, ?, ?)", token, userid, c.Request.Header.Get("User-Agent"))
|
_, err = conn.Exec("INSERT INTO sessions (session, id, device) VALUES (?, ?, ?)", token, userid, c.Request.Header.Get("User-Agent"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/signup session Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/signup session Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-SESSIONINSERT"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SIGNUP-SESSIONINSERT"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -445,28 +397,6 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
enableAPIVersion2 := false
|
|
||||||
enableAPIVersion1 := false
|
|
||||||
version1PasswordChange, _ := data["newpass"].(string)
|
|
||||||
versionCheck := c.GetHeader("X-Burgernotes-Version")
|
|
||||||
if versionCheck != "" {
|
|
||||||
versionCheckInt, err := strconv.Atoi(versionCheck)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("[ERROR] Unknown in /api/login versionCheck at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-VERSIONCHECK"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if versionCheckInt > 199 {
|
|
||||||
enableAPIVersion2 = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if version1PasswordChange != "" {
|
|
||||||
enableAPIVersion1 = true
|
|
||||||
} else {
|
|
||||||
enableAPIVersion1 = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
username, ok := data["username"].(string)
|
username, ok := data["username"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
|
@ -483,15 +413,14 @@ func main() {
|
||||||
c.JSON(401, gin.H{"error": "User does not exist"})
|
c.JSON(401, gin.H{"error": "User does not exist"})
|
||||||
return
|
return
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/login checkUsernameTaken() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/login checkUsernameTaken():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-USERTAKEN"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-USERTAKEN"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if enableAPIVersion2 || enableAPIVersion1 {
|
|
||||||
_, _, hashedPasswd, err := getUser(userid)
|
_, _, hashedPasswd, err := getUser(userid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/login getUser() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/login getUser():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-GETUSER"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-GETUSER"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -502,7 +431,7 @@ func main() {
|
||||||
c.JSON(422, gin.H{"error": "Invalid hash format"})
|
c.JSON(422, gin.H{"error": "Invalid hash format"})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
log.Println("[ERROR] Unknown in /api/login verifyHash() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/login verifyHash():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-VERIFYHASH"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-VERIFYHASH"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -511,89 +440,25 @@ func main() {
|
||||||
c.JSON(401, gin.H{"error": "Incorrect password"})
|
c.JSON(401, gin.H{"error": "Incorrect password"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
var legacyPassword string
|
|
||||||
err = conn.QueryRow("SELECT versionTwoLegacyPassword FROM users WHERE id = ?", userid).Scan(&legacyPassword)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("[ERROR] Unknown in /api/login legacyPassword query at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-LEGACYQUERY"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
hashedPassword := hashSha3(128, password)
|
|
||||||
|
|
||||||
correctPassword, err := verifyHash(hashedPassword, password)
|
token, err := randomChars(512)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, errors.New("invalid hash format")) {
|
log.Println("[ERROR] Unknown in /api/login token randomChars():", err)
|
||||||
c.JSON(422, gin.H{"error": "Invalid hash format"})
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
log.Println("[ERROR] Unknown in /api/login verifyHash() legacy at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-VERIFYHASH"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !correctPassword {
|
|
||||||
c.JSON(401, gin.H{"error": "Incorrect password"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if enableAPIVersion1 && version1PasswordChange != "null" {
|
|
||||||
salt, err := genSalt(16)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("[ERROR] Unknown in /api/login genSalt() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-SALT"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
hashedPassword, err := hash(version1PasswordChange, salt)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("[ERROR] Unknown in /api/login hash() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-HASH"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, err = conn.Exec("UPDATE users SET password = ? WHERE id = ?", hashedPassword, userid)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("[ERROR] Unknown in /api/login Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-DBUPDATE"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
token, err := genSalt(512)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("[ERROR] Unknown in /api/login token genSalt() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-SESSIONSALT"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-SESSIONSALT"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = conn.Exec("INSERT INTO sessions (session, id, device) VALUES (?, ?, ?)", token, userid, c.Request.Header.Get("User-Agent"))
|
_, err = conn.Exec("INSERT INTO sessions (session, id, device) VALUES (?, ?, ?)", token, userid, c.Request.Header.Get("User-Agent"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/login session Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/login session Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-SESSIONINSERT"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-SESSIONINSERT"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if enableAPIVersion2 {
|
|
||||||
var legacyPassword string
|
|
||||||
err = conn.QueryRow("SELECT versionTwoLegacyPassword FROM users WHERE id = ?", userid).Scan(&legacyPassword)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("[ERROR] Unknown in /api/login legacyPassword query at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-LEGACYQUERY"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if legacyPassword != "nil" {
|
|
||||||
c.JSON(200, gin.H{"key": token, "legacyPasswordNeeded": true})
|
|
||||||
} else {
|
|
||||||
c.JSON(200, gin.H{"key": token, "legacyPasswordNeeded": false})
|
|
||||||
}
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
c.JSON(200, gin.H{"key": token})
|
c.JSON(200, gin.H{"key": token})
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
router.POST("/api/v2/addlegacypassword", func(c *gin.Context) {
|
router.POST("/api/oauth/get", func(c *gin.Context) {
|
||||||
var data map[string]interface{}
|
var data map[string]interface{}
|
||||||
err := c.ShouldBindJSON(&data)
|
err := c.ShouldBindJSON(&data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -601,20 +466,42 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
versionCheck := c.GetHeader("X-Burgernotes-Version")
|
username, ok := data["username"].(string)
|
||||||
if versionCheck != "" {
|
if !ok {
|
||||||
versionCheckInt, err := strconv.Atoi(versionCheck)
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
oauthProvider, ok := data["oauthProvider"].(string)
|
||||||
|
if !ok {
|
||||||
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, userid, err := checkUsernameTaken(username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/login versionCheck at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
c.JSON(404, gin.H{"error": "Username not found"})
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-ADDLEGACYPASSWORD-VERSIONCHECK"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if versionCheckInt < 200 {
|
|
||||||
c.JSON(400, gin.H{"error": "This API can only be accessed by Burgernotes 2.0 and above"})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var encryptedPasswd string
|
||||||
|
err = conn.QueryRow("SELECT encryptedPasswd FROM oauth WHERE id = ? AND oauthProvider = ?", userid, oauthProvider).Scan(&encryptedPasswd)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
c.JSON(404, gin.H{"error": "Entry not found"})
|
||||||
} else {
|
} else {
|
||||||
c.JSON(400, gin.H{"error": "This API can only be accessed by Burgernotes 2.0 and above"})
|
log.Println("[ERROR] Unknown in /api/oauth/get select:", err)
|
||||||
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-OAUTH-GET-SELECT"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, gin.H{"password": encryptedPasswd})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.POST("/api/oauth/add", func(c *gin.Context) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
err := c.ShouldBindJSON(&data)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,24 +510,70 @@ func main() {
|
||||||
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
legacyPassword, ok := data["legacyPassword"].(string)
|
oauthProvider, ok := data["oauthProvider"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
encryptedPassword, ok := data["encryptedPassword"].(string)
|
||||||
|
if !ok {
|
||||||
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
|
}
|
||||||
|
|
||||||
_, userid, err := getSession(token)
|
_, userid, err := getSession(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(401, gin.H{"error": "Invalid session"})
|
c.JSON(401, gin.H{"error": "Invalid session"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = conn.Exec("UPDATE users SET versionTwoLegacyPassword = ? WHERE id = ?", legacyPassword, userid)
|
_, err = conn.Exec("INSERT INTO oauth (id, oauthProvider, encryptedPasswd) VALUES (?, ?, ?)", userid, oauthProvider, encryptedPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/login/addlegacypassword Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
if errors.Is(err, sqlite3.ErrConstraintUnique) {
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LOGIN-ADDLEGACYPASSWORD"})
|
c.JSON(409, gin.H{"error": "Entry already exists"})
|
||||||
|
} else {
|
||||||
|
log.Println("[ERROR] Unknown in /api/oauth/add Exec():", err)
|
||||||
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-OAUTH-ADD-EXEC"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, gin.H{"success": true})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.POST("/api/oauth/remove", func(c *gin.Context) {
|
||||||
|
var data map[string]interface{}
|
||||||
|
err := c.ShouldBindJSON(&data)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
token, ok := data["secretKey"].(string)
|
||||||
|
if !ok {
|
||||||
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
oauthProvider, ok := data["oauthProvider"].(string)
|
||||||
|
if !ok {
|
||||||
|
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, userid, err := getSession(token)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(401, gin.H{"error": "Invalid session"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = conn.Exec("DELETE FROM oauth WHERE userid = ? AND oauthProvider = ?", userid, oauthProvider)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
c.JSON(404, gin.H{"error": "Entry not found"})
|
||||||
|
} else {
|
||||||
|
log.Println("[ERROR] Unknown in /api/oauth/add Exec():", err)
|
||||||
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-OAUTH-REMOVE-EXEC"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.JSON(200, gin.H{"success": true})
|
c.JSON(200, gin.H{"success": true})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -669,22 +602,22 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
salt, err := genSalt(16)
|
salt, err := randomChars(16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/changepassword genSalt() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/changepassword randomChars():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-CHANGEPASSWORD-SALT"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-CHANGEPASSWORD-SALT"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hashedPassword, err := hash(newPassword, salt)
|
hashedPassword, err := hash(newPassword, salt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/changepassword hash() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/changepassword hash():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-CHANGEPASSWORD-HASH"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-CHANGEPASSWORD-HASH"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = conn.Exec("UPDATE users SET password = ? WHERE id = ?", hashedPassword, userid)
|
_, err = conn.Exec("UPDATE users SET password = ? WHERE id = ?", hashedPassword, userid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/changepassword Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/changepassword Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-CHANGEPASSWORD-DBUPDATE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-CHANGEPASSWORD-DBUPDATE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -713,21 +646,21 @@ func main() {
|
||||||
|
|
||||||
created, username, _, err := getUser(userid)
|
created, username, _, err := getUser(userid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/userinfo getUser() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/userinfo getUser():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-USERINFO-GETUSER"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-USERINFO-GETUSER"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
space, err := getSpace(userid)
|
space, err := getSpace(userid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/userinfo getSpace() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/userinfo getSpace():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-USERINFO-GETSPACE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-USERINFO-GETSPACE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
notecount, err := getNoteCount(userid)
|
notecount, err := getNoteCount(userid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/userinfo getNoteCount() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/userinfo getNoteCount():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-USERINFO-GETNOTECOUNT"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-USERINFO-GETNOTECOUNT"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -784,7 +717,7 @@ func main() {
|
||||||
c.JSON(200, []map[string]interface{}{})
|
c.JSON(200, []map[string]interface{}{})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
log.Println("[ERROR] Unknown in /api/listnotes query at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/listnotes query:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTNOTES-DBQUERY"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTNOTES-DBQUERY"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -792,7 +725,7 @@ func main() {
|
||||||
defer func(rows *sql.Rows) {
|
defer func(rows *sql.Rows) {
|
||||||
err := rows.Close()
|
err := rows.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/listnotes row defer at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/listnotes row defer:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTNOTES-ROWCLOSE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTNOTES-ROWCLOSE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -803,14 +736,14 @@ func main() {
|
||||||
var id int
|
var id int
|
||||||
var title string
|
var title string
|
||||||
if err := rows.Scan(&id, &title); err != nil {
|
if err := rows.Scan(&id, &title); err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/listnotes row scan at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/listnotes row scan:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTNOTES-ROWSCAN"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTNOTES-ROWSCAN"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
notes = append(notes, map[string]interface{}{"id": id, "title": title})
|
notes = append(notes, map[string]interface{}{"id": id, "title": title})
|
||||||
}
|
}
|
||||||
if err := rows.Err(); err != nil {
|
if err := rows.Err(); err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/listnotes row iteration at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/listnotes row iteration:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTNOTES-ROWERR"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTNOTES-ROWERR"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -843,7 +776,7 @@ func main() {
|
||||||
c.JSON(200, []map[string]interface{}{})
|
c.JSON(200, []map[string]interface{}{})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
log.Println("[ERROR] Unknown in /api/exportnotes query at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/exportnotes query:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-EXPORTNOTES-DBQUERY"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-EXPORTNOTES-DBQUERY"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -851,7 +784,7 @@ func main() {
|
||||||
defer func(rows *sql.Rows) {
|
defer func(rows *sql.Rows) {
|
||||||
err := rows.Close()
|
err := rows.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/exportnotes row defer at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/exportnotes row defer:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-EXPORTNOTES-ROWCLOSE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-EXPORTNOTES-ROWCLOSE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -862,14 +795,14 @@ func main() {
|
||||||
var id int
|
var id int
|
||||||
var created, edited, title, content string
|
var created, edited, title, content string
|
||||||
if err := rows.Scan(&id, &created, &edited, &title, &content); err != nil {
|
if err := rows.Scan(&id, &created, &edited, &title, &content); err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/exportnotes row scan at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/exportnotes row scan:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-EXPORTNOTES-ROWSCAN"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-EXPORTNOTES-ROWSCAN"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
notes = append(notes, map[string]interface{}{"id": id, "created": created, "edited": edited, "title": title, "content": content})
|
notes = append(notes, map[string]interface{}{"id": id, "created": created, "edited": edited, "title": title, "content": content})
|
||||||
}
|
}
|
||||||
if err := rows.Err(); err != nil {
|
if err := rows.Err(); err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/exportnotes row iteration at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/exportnotes row iteration:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-EXPORTNOTES-ROWERR"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-EXPORTNOTES-ROWERR"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -913,7 +846,7 @@ func main() {
|
||||||
note := note.(map[string]interface{})
|
note := note.(map[string]interface{})
|
||||||
_, err := conn.Exec("INSERT INTO notes (creator, created, edited, title, content) VALUES (?, ?, ?, ?, ?)", userid, note["created"], note["edited"], note["title"], note["content"])
|
_, err := conn.Exec("INSERT INTO notes (creator, created, edited, title, content) VALUES (?, ?, ?, ?, ?)", userid, note["created"], note["edited"], note["title"], note["content"])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/importnotes Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/importnotes Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-IMPORTNOTES-DBINSERT"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-IMPORTNOTES-DBINSERT"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -953,7 +886,7 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
_, err := conn.Exec("INSERT INTO notes (title, content, creator, created, edited) VALUES (?, ?, ?, ?, ?)", noteName, "", userid, strconv.FormatInt(time.Now().Unix(), 10), strconv.FormatInt(time.Now().Unix(), 10))
|
_, err := conn.Exec("INSERT INTO notes (title, content, creator, created, edited) VALUES (?, ?, ?, ?, ?)", noteName, "", userid, strconv.FormatInt(time.Now().Unix(), 10), strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/newnote Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/newnote Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-NEWNOTE-DBINSERT"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-NEWNOTE-DBINSERT"})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
@ -994,7 +927,7 @@ func main() {
|
||||||
c.JSON(422, gin.H{"error": "Note not found"})
|
c.JSON(422, gin.H{"error": "Note not found"})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
log.Println("[ERROR] Unknown in /api/readnote getNote() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/readnote getNote():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-READNOTE-GETNOTE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-READNOTE-GETNOTE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1030,7 +963,7 @@ func main() {
|
||||||
|
|
||||||
_, err = conn.Exec("DELETE FROM notes WHERE creator = ?", userid)
|
_, err = conn.Exec("DELETE FROM notes WHERE creator = ?", userid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/purgenotes Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/purgenotes Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-PURGENOTES-DBDELETE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-PURGENOTES-DBDELETE"})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
@ -1080,7 +1013,7 @@ func main() {
|
||||||
c.JSON(422, gin.H{"error": "Note not found"})
|
c.JSON(422, gin.H{"error": "Note not found"})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
log.Println("[ERROR] Unknown in /api/editnote getNote() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/editnote getNote():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-EDITNOTE-GETNOTE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-EDITNOTE-GETNOTE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1092,7 +1025,7 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
_, err := conn.Exec("UPDATE notes SET content = ?, title = ?, edited = ? WHERE id = ?", content, title, strconv.FormatInt(time.Now().Unix(), 10), noteId)
|
_, err := conn.Exec("UPDATE notes SET content = ?, title = ?, edited = ? WHERE id = ?", content, title, strconv.FormatInt(time.Now().Unix(), 10), noteId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/editnote Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/editnote Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-EDITNOTE-DBUPDATE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-EDITNOTE-DBUPDATE"})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
@ -1133,7 +1066,7 @@ func main() {
|
||||||
c.JSON(422, gin.H{"error": "Note not found"})
|
c.JSON(422, gin.H{"error": "Note not found"})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
log.Println("[ERROR] Unknown in /api/removenote getNote() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/removenote getNote():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-REMOVENOTE-GETNOTE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-REMOVENOTE-GETNOTE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1145,7 +1078,7 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
_, err := conn.Exec("DELETE FROM notes WHERE id = ?", noteId)
|
_, err := conn.Exec("DELETE FROM notes WHERE id = ?", noteId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/removenote Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/removenote Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-REMOVENOTE-DBDELETE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-REMOVENOTE-DBDELETE"})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
@ -1176,21 +1109,21 @@ func main() {
|
||||||
|
|
||||||
_, err = conn.Exec("DELETE FROM notes WHERE creator = ?", userid)
|
_, err = conn.Exec("DELETE FROM notes WHERE creator = ?", userid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/deleteaccount notes Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/deleteaccount notes Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-DELETEACCOUNT-NOTESDELETE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-DELETEACCOUNT-NOTESDELETE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = conn.Exec("DELETE FROM users WHERE id = ?", userid)
|
_, err = conn.Exec("DELETE FROM users WHERE id = ?", userid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/deleteaccount user Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/deleteaccount user Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-DELETEACCOUNT-USERDELETE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-DELETEACCOUNT-USERDELETE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = conn.Exec("DELETE FROM sessions WHERE id = ?", userid)
|
_, err = conn.Exec("DELETE FROM sessions WHERE id = ?", userid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/deleteaccount session Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/deleteaccount session Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-DELETEACCOUNT-SESSIONDELETE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-DELETEACCOUNT-SESSIONDELETE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1224,7 +1157,7 @@ func main() {
|
||||||
c.JSON(200, []map[string]interface{}{})
|
c.JSON(200, []map[string]interface{}{})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
log.Println("[ERROR] Unknown in /api/sessions/list query at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/sessions/list query:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SESSIONS-LIST-DBQUERY"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SESSIONS-LIST-DBQUERY"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1232,7 +1165,7 @@ func main() {
|
||||||
defer func(rows *sql.Rows) {
|
defer func(rows *sql.Rows) {
|
||||||
err := rows.Close()
|
err := rows.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/sessions/list row defer at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/sessions/list row defer:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SESSIONS-LIST-ROWCLOSE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SESSIONS-LIST-ROWCLOSE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1243,7 +1176,7 @@ func main() {
|
||||||
var sessionid int
|
var sessionid int
|
||||||
var session, device string
|
var session, device string
|
||||||
if err := rows.Scan(&sessionid, &session, &device); err != nil {
|
if err := rows.Scan(&sessionid, &session, &device); err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/sessions/list row scan at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/sessions/list row scan:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SESSIONS-LIST-ROWSCAN"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SESSIONS-LIST-ROWSCAN"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1254,7 +1187,7 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := rows.Err(); err != nil {
|
if err := rows.Err(); err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/sessions/list row iteration at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/sessions/list row iteration:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SESSIONS-LIST-ROWERR"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SESSIONS-LIST-ROWERR"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1294,7 +1227,7 @@ func main() {
|
||||||
c.JSON(422, gin.H{"error": "Target session not found"})
|
c.JSON(422, gin.H{"error": "Target session not found"})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
log.Println("[ERROR] Unknown in /api/sessions/remove getSession() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/sessions/remove getSession():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SESSIONS-REMOVE-GETSESSION"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SESSIONS-REMOVE-GETSESSION"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1305,7 +1238,7 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
_, err := conn.Exec("DELETE FROM sessions WHERE sessionid = ?", sessionId)
|
_, err := conn.Exec("DELETE FROM sessions WHERE sessionid = ?", sessionId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/sessions/remove Exec() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/sessions/remove Exec():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SESSIONS-REMOVE-DBDELETE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-SESSIONS-REMOVE-DBDELETE"})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
@ -1335,7 +1268,7 @@ func main() {
|
||||||
c.JSON(200, []map[string]interface{}{})
|
c.JSON(200, []map[string]interface{}{})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
log.Println("[ERROR] Unknown in /api/listusers query at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/listusers query:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTUSERS-DBQUERY"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTUSERS-DBQUERY"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1343,7 +1276,7 @@ func main() {
|
||||||
defer func(rows *sql.Rows) {
|
defer func(rows *sql.Rows) {
|
||||||
err := rows.Close()
|
err := rows.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/listusers row defer at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/listusers row defer:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTUSERS-ROWCLOSE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTUSERS-ROWCLOSE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1354,26 +1287,26 @@ func main() {
|
||||||
var id int
|
var id int
|
||||||
var username, created string
|
var username, created string
|
||||||
if err := rows.Scan(&id, &username, &created); err != nil {
|
if err := rows.Scan(&id, &username, &created); err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/listusers row scan at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/listusers row scan:", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTUSERS-ROWSCAN"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTUSERS-ROWSCAN"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
space, err := getSpace(id)
|
space, err := getSpace(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/listusers getSpace() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/listusers getSpace():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTUSERS-GETSPACE"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTUSERS-GETSPACE"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
notes, err := getNoteCount(id)
|
notes, err := getNoteCount(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/listusers getNoteCount() at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/listusers getNoteCount():", err)
|
||||||
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTUSERS-GETNOTECOUNT"})
|
c.JSON(500, gin.H{"error": "Something went wrong on our end. Please report this bug at https://centrifuge.hectabit.org/hectabit/burgernotes and refer to the documentation for more info. Your error code is: UNKNOWN-API-LISTUSERS-GETNOTECOUNT"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
users = append(users, map[string]interface{}{"id": id, "username": username, "created": created, "space": space, "notes": notes})
|
users = append(users, map[string]interface{}{"id": id, "username": username, "created": created, "space": space, "notes": notes})
|
||||||
}
|
}
|
||||||
if err := rows.Err(); err != nil {
|
if err := rows.Err(); err != nil {
|
||||||
log.Println("[ERROR] Unknown in /api/listusers row iteration at", strconv.FormatInt(time.Now().Unix(), 10)+":", err)
|
log.Println("[ERROR] Unknown in /api/listusers row iteration:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
10
schema.sql
10
schema.sql
|
@ -6,8 +6,7 @@ CREATE TABLE users (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
created TEXT NOT NULL,
|
created TEXT NOT NULL,
|
||||||
username TEXT NOT NULL,
|
username TEXT NOT NULL,
|
||||||
password TEXT NOT NULL,
|
password TEXT NOT NULL
|
||||||
versionTwoLegacyPassword TEXT NOT NULL DEFAULT 'nil',
|
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE notes (
|
CREATE TABLE notes (
|
||||||
|
@ -25,3 +24,10 @@ CREATE TABLE sessions (
|
||||||
id INTEGER NOT NULL,
|
id INTEGER NOT NULL,
|
||||||
device TEXT NOT NULL DEFAULT '?'
|
device TEXT NOT NULL DEFAULT '?'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE oauth (
|
||||||
|
id INTEGER NOT NULL,
|
||||||
|
oauthProvider TEXT NOT NULL,
|
||||||
|
encryptedPasswd TEXT NOT NULL,
|
||||||
|
UNIQUE (id, oauthProvider)
|
||||||
|
)
|
Loading…
Reference in New Issue