General message clarifications

This commit is contained in:
Paul 2023-02-23 02:21:12 +01:00 committed by Pierre-Olivier Mercier
parent 98d81809b3
commit fd8876da75
12 changed files with 57 additions and 55 deletions

View File

@ -21,13 +21,13 @@ It runs as a single stateless Linux binary, backed by a database (currently: Lev
Using Docker
------------
We are a Docker sponsored OSS project! thus you can easily try and/or deploy our app using Docker/podman/kubernetes/...:
We are a Docker sponsored OSS project! Thus you can easily try and/or deploy our app using Docker/podman/kubernetes/...:
```
docker run -e HAPPYDOMAIN_NO_AUTH=1 -p 8081:8081 happydomain/happydomain
```
This command will launch happyDomain in a few seconds, for evaluation purpose (no authentication, volatile storage, ...). With your browser, just go to <http://localhost:8081> and enjoy!
This command will launch happyDomain in a few seconds, for evaluation purposes (no authentication, volatile storage, ...). With your browser, just go to <http://localhost:8081> and enjoy!
In order to deploy happyDomain, check the [Docker image documentation](https://hub.docker.com/r/happydomain/happydomain).
@ -47,12 +47,10 @@ In order to build the happyDomain project, you'll need the following dependencie
1. First, you'll need to prepare the frontend, by installing the node modules dependencies:
```
(cd ui; npm install)
pushd ui; npm install; popd
```
*If you forget the parenthesis, go back to the project root directory.*
2. Then, generates assets files used by Go code:
2. Then, generate assets files used by Go code:
```
go generate git.happydomain.org/happydomain/ui
@ -78,7 +76,7 @@ You can simply launch the following command in your terminal:
./happydomain
```
After some initializations, it should show you:
After some initialization, it should show you:
Admin listening on ./happydomain.sock
Ready, listening on :8081
@ -90,23 +88,27 @@ Go to http://localhost:8081/ to start using happyDomain.
By default, the LevelDB storage engine is used. You can change the storage engine using the option `-storage-engine other-engine`.
The help command `./happydomain -help` can show you the available engines. By example:
The help command `./happydomain -help` shows you the available engines:
```
-storage-engine value
Select the storage engine between [leveldb mysql] (default leveldb)
```
#### LevelDB
LevelDB is a small embedded key-value store (as SQLite it doesn't require an additional daemon to work).
```
-leveldb-path string
Path to the LevelDB Database (default "happydomain.db")
```
By default, a new directory is created near the binary, called `happydomain.db`. This directory contains the database used by the program.
You can change it to a more meaningful/persistant path.
### Persistant configuration
### Persistent configuration
The binary will automatically look for some existing configuration files:
@ -118,7 +120,7 @@ Only the first file found will be used.
It is also possible to specify a custom path by adding it as argument to the command line:
```
```sh
./happydomain /etc/happydomain/config
```

View File

@ -81,7 +81,7 @@ func retrieveUserFromClaims(claims *UserClaims) (user *happydns.User, err error)
err = storage.MainStore.UpdateUser(user)
if err != nil {
err = fmt.Errorf("has a correct JWT, but an error occurs when creating the user: %w", err)
err = fmt.Errorf("has a correct JWT, but an error occured when trying to create the user: %w", err)
return
}
} else if time.Since(user.LastSeen) > time.Hour*12 {
@ -90,7 +90,7 @@ func retrieveUserFromClaims(claims *UserClaims) (user *happydns.User, err error)
err = storage.MainStore.UpdateUser(user)
if err != nil {
err = fmt.Errorf("has a correct JWT, user has been found, but an error occurs when updating user's information: %w", err)
err = fmt.Errorf("has a correct JWT, user has been found, but an error occured when trying to update the user's information: %w", err)
return
}
}
@ -110,7 +110,7 @@ func retrieveSessionFromClaims(claims *UserClaims, user *happydns.User, session_
err = storage.MainStore.UpdateSession(session)
if err != nil {
err = fmt.Errorf("has a correct JWT, but an error occurs when creating the session: %w", err)
err = fmt.Errorf("has a correct JWT, but an error occured when trying to create the session: %w", err)
return
}
@ -119,7 +119,7 @@ func retrieveSessionFromClaims(claims *UserClaims, user *happydns.User, session_
err = storage.MainStore.UpdateUser(user)
if err != nil {
err = fmt.Errorf("has a correct JWT, session has been created, but an error occurs when updating user's information: %w", err)
err = fmt.Errorf("has a correct JWT, session has been created, but an error occured when trying to update the user's information: %w", err)
return
}
}
@ -169,7 +169,7 @@ func authMiddleware(opts *config.Options, optional bool) gin.HandlerFunc {
if err != nil {
log.Printf("%s provide a bad JWT claims: %s", c.ClientIP(), err.Error())
c.SetCookie(COOKIE_NAME, "", -1, opts.BaseURL+"/", "", opts.DevProxy == "", true)
requireLogin(opts, c, "Something goes wrong with your session. Please reconnect.")
requireLogin(opts, c, "Something went wrong with your session. Please reconnect.")
return
}
@ -177,14 +177,14 @@ func authMiddleware(opts *config.Options, optional bool) gin.HandlerFunc {
if len(claims.Profile.UserId) == 0 {
log.Printf("%s: no UserId found in JWT claims", c.ClientIP())
c.SetCookie(COOKIE_NAME, "", -1, opts.BaseURL+"/", "", opts.DevProxy == "", true)
requireLogin(opts, c, "Something goes wrong with your session. Please reconnect.")
requireLogin(opts, c, "Something went wrong with your session. Please reconnect.")
return
}
if claims.Profile.Email == "" {
log.Printf("%s: no Email found in JWT claims", c.ClientIP())
c.SetCookie(COOKIE_NAME, "", -1, opts.BaseURL+"/", "", opts.DevProxy == "", true)
requireLogin(opts, c, "Something goes wrong with your session. Please reconnect.")
requireLogin(opts, c, "Something went wrong with your session. Please reconnect.")
return
}
@ -193,7 +193,7 @@ func authMiddleware(opts *config.Options, optional bool) gin.HandlerFunc {
if err != nil {
log.Printf("%s %s", c.ClientIP(), err.Error())
c.SetCookie(COOKIE_NAME, "", -1, opts.BaseURL+"/", "", opts.DevProxy == "", true)
requireLogin(opts, c, "Something goes wrong with your session. Please reconnect.")
requireLogin(opts, c, "Something went wrong with your session. Please reconnect.")
return
}

View File

@ -141,7 +141,7 @@ func registerUser(opts *config.Options, c *gin.Context) {
if actions.SendValidationLink(opts, user); err != nil {
log.Printf("%s: unable to SendValidationLink in registerUser: %s", c.ClientIP(), err.Error())
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Sorry, we are currently unable to sent email validation link. Please try again later."})
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Sorry, we are currently unable to send email validation link. Please try again later."})
return
}
@ -170,7 +170,7 @@ func specialUserOperations(opts *config.Options, c *gin.Context) {
if user.EmailVerification == nil {
if err = actions.SendValidationLink(opts, user); err != nil {
log.Printf("%s: unable to SendValidationLink in specialUserOperations: %s", c.ClientIP(), err.Error())
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Sorry, we are currently unable to sent email validation link. Please try again later."})
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Sorry, we are currently unable to send email validation link. Please try again later."})
return
}
@ -178,7 +178,7 @@ func specialUserOperations(opts *config.Options, c *gin.Context) {
} else {
if err = actions.SendRecoveryLink(opts, user); err != nil {
log.Printf("%s: unable to SendRecoveryLink in specialUserOperations: %s", c.ClientIP(), err.Error())
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Sorry, we are currently unable to sent accont recovery link. Please try again later."})
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Sorry, we are currently unable to send accont recovery link. Please try again later."})
return
}

10
main.go
View File

@ -67,11 +67,11 @@ func main() {
// Initialize storage
if s, ok := storage.StorageEngines[opts.StorageEngine]; !ok {
log.Fatal(fmt.Sprintf("Unexistant storage engine: %q, please select one between: %v", opts.StorageEngine, storage.GetStorageEngines()))
log.Fatal(fmt.Sprintf("Nonexistent storage engine: %q, please select one of: %v", opts.StorageEngine, storage.GetStorageEngines()))
} else {
log.Println("Opening database...")
if store, err := s(); err != nil {
log.Fatal("Cannot open the database: ", err)
log.Fatal("Could not open the database: ", err)
} else {
defer store.Close()
storage.MainStore = store
@ -79,12 +79,12 @@ func main() {
}
if opts.NoAuth {
log.Println("WARNING: NoAuth option has to be use for testing or personnal purpose behind another restriction/authentication method.")
log.Println("WARNING: NoAuth option must be used for testing or private use behind another restriction/authentication method.")
}
log.Println("Do database migrations...")
log.Println("Performing database migrations...")
if err = storage.MainStore.DoMigration(); err != nil {
log.Fatal("Cannot migrate database: ", err)
log.Fatal("Could not migrate database: ", err)
}
// Prepare graceful shutdown

View File

@ -78,7 +78,7 @@ func (i Identifier) MarshalJSON() (dst []byte, err error) {
func (i *Identifier) UnmarshalJSON(src []byte) error {
if len(src) < 2 || src[0] != '"' || src[len(src)-1] != '"' {
return errors.New("Unvalid character found to encapsulate the JSON value")
return errors.New("Invalid character encapsulating the JSON value")
}
*i = make([]byte, base64.RawURLEncoding.DecodedLen(len(src)-2))

View File

@ -86,7 +86,7 @@ func init() {
acmechallenge_analyze,
svcs.ServiceInfos{
Name: "ACME Challenge",
Description: "Temporary record to prove that you are in possession of the sub-domain.",
Description: "Temporary record to prove that you control the sub-domain.",
Family: svcs.Abstract,
Categories: []string{
"temporary",

View File

@ -85,7 +85,7 @@ func init() {
googleverification_analyze,
svcs.ServiceInfos{
Name: "Google Verification",
Description: "Temporary record to prove that you are in possession of the domain.",
Description: "Temporary record to prove that you control the domain.",
Family: svcs.Abstract,
Categories: []string{
"temporary",

View File

@ -86,7 +86,7 @@ func init() {
keybaseverification_analyze,
svcs.ServiceInfos{
Name: "Keybase Verification",
Description: "Temporary record to prove that you are in possession of the domain.",
Description: "Temporary record to prove that you control the domain.",
Family: svcs.Abstract,
Categories: []string{
"temporary",

View File

@ -86,7 +86,7 @@ func init() {
scalewaychallenge_analyze,
svcs.ServiceInfos{
Name: "Scaleway Challenge",
Description: "Temporary record to prove that you are in possession of the domain.",
Description: "Temporary record to prove that you control the domain.",
Family: svcs.Abstract,
Categories: []string{
"temporary",

View File

@ -16,9 +16,9 @@
"signup": {
"already": "Already a member?",
"join-call": "Join our nice platform in less than 2 minutes!",
"address-why": "We'll use your address to {{identify}} yourself on the platform, and it could be used to contact you for {{security-operations}}.",
"address-why": "We'll use your address to {{identify}} you on this platform, and to contact you for {{security-operations}}.",
"identify": "identify",
"security-operations": "security related operations",
"security-operations": "security related reasons",
"receive-update": "Keep me informed of future big improvements",
"signup": "Sign up!",
"success": "Registration successfully performed!"
@ -48,7 +48,7 @@
"rename": "Rename",
"resolver": "Resolver",
"run": "Run the request!",
"survey": "A remark? a comment to share? Don't hesitate to write us!",
"survey": "A remark? A comment to share? Don't hesitate to write to us!",
"spinning": "Spinning",
"update": "Update",
"welcome": {
@ -65,10 +65,10 @@
"reimport": "Re-import",
"view": "View my zone",
"propagate": "Publish my changes",
"rollback": "Rollback to this version"
"rollback": "Roll back to this version"
},
"alert": {
"remove": "This action will permanently remove the domain {{domain}} from your managed domains. All history and abstracted zones will be discarded. This action will not delete or unregister your domain from your provider, nor alterate what is currently served. It will only affect what you see in happyDomain. Are you sure you want to continue?",
"remove": "This action only removes {{domain}} from your happyDomain managed domains. All history and abstracted zones will be discarded. The domain {{domain}} remains fully intact at the provider. Are you sure you want to continue?",
"unable-retrieve": {
"description": "Unfortunately, we were unable to retrieve information for the domain {{domain}}:",
"title": "Unable to retrieve domain information"
@ -161,7 +161,7 @@
"password": "Password is required",
"password-change": "Unable to change your password account",
"password-match": "Password and its confirmation doesn't match.",
"password-weak": "Password needs to be stronger: at least 8 characters with numbers, low case and high case characters.",
"password-weak": "Password needs to be stronger: at least 8 characters with numbers, lower case and upper case characters.",
"provider-delete": "Something went wrong during provider deletion",
"recovery": "Password recovery problem",
"resolve": "An error occurs when trying to resolve the domain.",
@ -178,33 +178,33 @@
},
"menu": {
"my-domains": "My domains",
"my-providers": "My domains' providers",
"my-providers": "My domain providers",
"dns-resolver": "DNS resolver",
"my-account": "My account",
"logout": "Logout",
"logout": "Sign out",
"signup": "Sign up",
"signin": "Sign in",
"quick-menu": "Quick Access"
},
"onboarding": {
"add-one": "add a new one",
"add-one": "add a new provider",
"choose-configured": "choose between already configured providers or {{action}}:",
"suggest-provider": "choose your provider:",
"use": "Use {{happyDomain}} as a remplacement interface to your usual domain name provider. It'll still rely on your provider's infrastructure, you'll just take benefit from our simple interface. As a first step, {{first-step}}",
"use": "Use {{happyDomain}} as a replacement interface to your usual domain name provider. It'll still rely on your provider's infrastructure, via our simple interface. As a first step, {{first-step}}",
"no-sale": {
"title": "I don't own any domain",
"description": "{{happyDomain}} does not sell domain yet. To start using our interface, you need to buy a domain from one of our supported provider",
"buy-advice": "We'll provide some guidance in a near future on how to easily buy a domain name. So stay tune and get in touch with us if you'll help us to build a comprehensive guide."
"description": "{{happyDomain}} does not sell domains yet. To start using our interface, you need to buy a domain from one of our supported providers.",
"buy-advice": "We'll provide some guidance in the near future on how to easily buy a domain name. So stay tuned and get in touch with us if you can help us build a comprehensive guide."
},
"own": "I already own a domain",
"questions": {
"hosting": {
"q": "I don't want to rely on my domain name hosting provider anymore. Can I host my domain name on your infrastructure",
"a": "We'll provide such feature in a near future, as it's on our manifest. We choose to focus first on spreading the word that domain names are accessibles to everyone through this sweet interface, before targeting privacy, censorship, …"
"q": "I don't want to rely on my domain name hosting provider anymore. Can I host my domain name on your infrastructure?",
"a": "We'll provide such a feature in the near future, as it's on our manifest. We choose to focus first on spreading the word that domain names are accessibles to everyone through this sweet interface, before targeting privacy, censorship, …"
},
"secondary": {
"q": "I've my own infrastructure, can I use {{happyDomain}} as secondary authoritative server?",
"a": "We'll provide such feature in a near future, as soon as our name server infrastructure is on."
"q": "I have my own infrastructure. Can I use {{happyDomain}} as a secondary authoritative server?",
"a": "We'll provide such feature in a near future, as soon as our name server infrastructure is ready."
}
}
},
@ -239,11 +239,11 @@
"empty": "You have no provider defined currently. Try {{action}}!",
"empty-action": "adding one",
"find": "Can't find your domain provider here?",
"name-your": "Name your domain's provider",
"name-your": "Name your domain provider",
"no-name": "No name",
"provider": "Domains living on {{provider}}",
"kind": "domain's provider",
"select-provider": "First, you need to select the provider hosting your domain:",
"select-provider": "First, select the provider hosting your domain:",
"provider-name": "Host's name",
"provider-type": "Hosting provider type",
"title": "Your domains' providers",

View File

@ -59,7 +59,7 @@ export function passRestrictions(svcinfo: ServiceInfos, provider_specs: Provider
if (svcinfo.restrictions.alone) {
for (const s of zservices[dn]) {
if (s._svctype !== svcinfo._svctype && sspecs[s._svctype].restrictions && !sspecs[s._svctype].restrictions.nearAlone) {
return 'has to be the only one in the subdomain.';
return 'only one per subdomain.';
}
}
}
@ -69,7 +69,7 @@ export function passRestrictions(svcinfo: ServiceInfos, provider_specs: Provider
for (const s of zservices[dn]) {
for (const exclu of svcinfo.restrictions.exclusive) {
if (s._svctype === exclu) {
return 'cannot be present along with ' + sspecs[s._svctype].name + '.';
return 'cannot coexist with ' + sspecs[s._svctype].name + '.';
}
}
}
@ -83,7 +83,7 @@ export function passRestrictions(svcinfo: ServiceInfos, provider_specs: Provider
}
for (const i in s.restrictions.exclusive) {
if (svcinfo._svctype === s.restrictions.exclusive[i]) {
return 'cannot be present along with ' + sspecs[s._svctype].name + '.';
return 'cannot coexist with ' + sspecs[s._svctype].name + '.';
}
}
}
@ -109,10 +109,10 @@ export function passRestrictions(svcinfo: ServiceInfos, provider_specs: Provider
}
}
if (oneAlone && oneAlone !== svcinfo._svctype && !svcinfo.restrictions.nearAlone) {
return 'cannot be present along with ' + sspecs[oneAlone].name + ', that requires to be the only one in subdomain.';
return 'cannot coexist with ' + sspecs[oneAlone].name + ', that requires to be the only one in the subdomain.';
}
if (oneLeaf && oneLeaf !== svcinfo._svctype && !svcinfo.restrictions.glue) {
return 'cannot be present along with ' + sspecs[oneLeaf].name + ', that requires to don\'t have subdomains.';
return 'cannot coexist with ' + sspecs[oneLeaf].name + ', that cannot have subdomains.';
}
}

View File

@ -14,7 +14,7 @@ function createToastsStore() {
};
const addErrorToast = (o: NewToast) => {
if (!o.title) o.title = 'Une erreur est survenue !';
if (!o.title) o.title = 'An error occured!';
if (!o.type) o.type = 'error';
return addToast(o);