Skip to content

Commit

Permalink
rename recover to reset
Browse files Browse the repository at this point in the history
  • Loading branch information
or-else committed Sep 30, 2018
1 parent 8541ae9 commit 1870fff
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 33 deletions.
31 changes: 20 additions & 11 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
- [Creating an Account](#creating-an-account)
- [Logging in](#logging-in)
- [Changing Authentication Parameters](#changing-authentication-parameters)
- [Password Recovery](#password-recovery)
- [Resetting a Password](#resetting-a-password)
- [Credentials](#credentials)
- [Access control](#access-control)
- [Topics](#topics)
Expand Down Expand Up @@ -169,25 +169,32 @@ User may optionally set `{acc login=true}` to use the new account for immediate

#### Logging in

Logging in is possible with `basic` and `token` only. Response to any login is a `{ctrl}` message with either a code 200 and a token which can be used in subsequent logins with `token` authentication, or a code 300 request for additional information, such as verifying credentials or responding to a method-dependent challenge in multi-step authentication, or a code 4xx error.
Logging in is performed by issuing a `{login}` request. Logging in is possible with `basic` and `token` only. Response to any login is a `{ctrl}` message with either a code 200 and a token which can be used in subsequent logins with `token` authentication, or a code 300 request for additional information, such as verifying credentials or responding to a method-dependent challenge in multi-step authentication, or a code 4xx error.

Token has server-configured expiration time so it needs to be periodically refreshed.

#### Changing Authentication Parameters

User may change authentication parameters, such as changing login and password, by issuing an `{acc}` request on an already authenticated session. Only `basic` authentication currently supports changing parameters:
User may change authentication parameters, such as changing login and password, by issuing an `{acc}` request. Only `basic` authentication currently supports changing parameters:
```js
acc: {
id: "1a2b3", // string, client-provided message id, optional
scheme: "basic", // authentication scheme being updated
user: "usr2il9suCbuko", // user, who is being affected by the change, optional
token: "XMg...g1Gp8+BO0=", // authentication token if the session is not yet authenticated, optional.
scheme: "basic", // authentication scheme being updated.
secret: btoa("new_username:new_password") // new parameters
}
```
In order to change just the password, `username` should be left empty, i.e. `secret: btoa(":new_password")`.

#### Password Recovery
If the session is not authenticated, the request must include a `token`. It can be a regular authentication token obtained during login, or a restricted token received through [Resetting a Password](#resetting-a-password) process. If the session is authenticated, the token must not be included. If the request is authenticated for access level `ROOT`, then the `user` may be set to a valid ID of another user. Otherwise it must be blank (defaulting to the current user) or equal to the ID of the current user.

Currently not supported.

#### Resetting a Password

To reset a password (or any other authentication secret, if such action is supported by the authenticator), one sends a `{login}` message with the `scheme` set to `reset` and the `secret` containing a base64-encoded string "`authentication scheme to reset secret for`:`reset method`:`reset method value`". Most basic case of resetting a password by email is `secret: btoa("basic:email:jdoe@example.com")`, where `jdoe@example.com` is an earlier validated user's email.

If the email matches the registration, the server will send a message using specified method an address with instructions for resetting the secret. The email contains a restricted security token which the user can include into an `{acc}` request with the new secret as described in [Changing Authentication Parameters](#changing-authentication-parameters).

### Credentials

Expand Down Expand Up @@ -507,9 +514,9 @@ hi: {
ver: "0.14", // string, version of the wire protocol supported by the client, required
ua: "JS/1.0 (Windows 10)", // string, user agent identifying client software,
// optional
dev: "L1iC2dNtk2", // string, unique value which identifies this specific
dev: "L1iC2...dNtk2", // string, unique value which identifies this specific
// connected device for the purpose of push notifications; not
// interpreted by the server; optional
// interpreted by the server.
// see [Push notifications support](#push-notifications-support); optional
lang: "EN" // human language of the client device; optional
}
Expand All @@ -524,6 +531,8 @@ Message `{acc}` creates users or updates `tags` or authentication credentials `s
acc: {
id: "1a2b3", // string, client-provided message id, optional
user: "new", // string, "new" to create a new user, default: current user, optional
token: "XMgS...8+BO0=", // string, authentication token to use for the request if the
// session is not authenticated, optional
scheme: "basic", // authentication scheme for this account, required;
// "basic" and "anon" are currently supported for account creation.
secret: btoa("username:password"), // string, base64 encoded secret for the chosen
Expand Down Expand Up @@ -572,8 +581,8 @@ Login is used to authenticate the current session.
```js
login: {
id: "1a2b3", // string, client-provided message id, optional
scheme: "basic", // string, authentication scheme, optional; "basic" and "token"
// are currently supported
scheme: "basic", // string, authentication scheme; "basic",
// "token", and "reset" are currently supported
secret: btoa("username:password"), // string, base64-encoded secret for the chosen
// authentication scheme, required
cred: [
Expand All @@ -587,7 +596,7 @@ login: {
```
The `basic` authentication scheme expects `secret` to be a base64-encoded string of a string composed of a user name followed by a colon `:` followed by a plan text password. User name in the `basic` scheme must not contain colon character ':' (ASCII 0x3A). The `token` expects secret to be a previously obtained security token.

The only supported authentication schemes are `basic` and `token`. Although `anonymous` scheme can be used to create accounts, it cannot be used for logging in.
The only supported authentication schemes are `basic` and `token`. Although `anon` scheme can be used to create accounts, it cannot be used for logging in. A scheme `reset` can be used for password reset.

Server responds to a `{login}` packet with a `{ctrl}` message. The `params` of the message contains the id of the logged in user as `user`. The `token` contains an encrypted string which can be used for authentication. Expiration time of the token is passed as `expires`.

Expand Down
12 changes: 6 additions & 6 deletions server/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -691,8 +691,8 @@ func (s *Session) login(msg *ClientComMessage) {
return
}

if msg.Login.Scheme == "recover" {
s.queueOut(decodeStoreError(s.authSecretRecovery(msg.Login.Secret), msg.Login.Id, "", msg.timestamp, nil))
if msg.Login.Scheme == "reset" {
s.queueOut(decodeStoreError(s.authSecretReset(msg.Login.Secret), msg.Login.Id, "", msg.timestamp, nil))
return
}

Expand Down Expand Up @@ -735,9 +735,9 @@ func (s *Session) login(msg *ClientComMessage) {
}
}

// authSecretRecovery performs password recovery;
// params: "auth-method-to-recover:credential-method:credential-value".
func (s *Session) authSecretRecovery(params []byte) error {
// authSecretReset resets an authentication secret;
// params: "auth-method-to-reset:credential-method:credential-value".
func (s *Session) authSecretReset(params []byte) error {
var authScheme, credMethod, credValue string
if parts := strings.Split(string(params), ":"); len(parts) == 3 {
authScheme, credMethod, credValue = parts[0], parts[1], parts[2]
Expand Down Expand Up @@ -772,7 +772,7 @@ func (s *Session) authSecretRecovery(params []byte) error {
return err
}

return validator.Recover(credValue, authScheme, s.lang, token)
return validator.ResetSecret(credValue, authScheme, s.lang, token)
}

// onLogin performs steps after successful authentication.
Expand Down
File renamed without changes.
20 changes: 10 additions & 10 deletions server/validate/email/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ import (
type validator struct {
HostUrl string `json:"host_url"`
ValidationTemplFile string `json:"validation_body_templ"`
RecoveryTemplFile string `json:"recovery_body_templ"`
ResetTemplFile string `json:"reset_body_templ"`
ValidationSubject string `json:"validation_subject"`
RecoverySubject string `json:"recovery_subject"`
ResetSubject string `json:"reset_subject"`
SendFrom string `json:"sender"`
SenderPassword string `json:"sender_password"`
DebugResponse string `json:"debug_response"`
MaxRetries int `json:"max_retries"`
SMTPAddr string `json:"smtp_server"`
SMTPPort string `json:"smtp_port"`
htmlValidationTempl *ht.Template
htmlRecoveryTempl *ht.Template
htmlResetTempl *ht.Template
auth smtp.Auth
}

Expand Down Expand Up @@ -74,18 +74,18 @@ func (v *validator) Init(jsonconf string) error {
v.ValidationTemplFile = filepath.Join(filepath.Dir(basepath), v.ValidationTemplFile)
}
}
if !filepath.IsAbs(v.RecoveryTemplFile) {
if !filepath.IsAbs(v.ResetTemplFile) {
basepath, err := os.Executable()
if err == nil {
v.RecoveryTemplFile = filepath.Join(filepath.Dir(basepath), v.RecoveryTemplFile)
v.ResetTemplFile = filepath.Join(filepath.Dir(basepath), v.ResetTemplFile)
}
}

v.htmlValidationTempl, err = ht.ParseFiles(v.ValidationTemplFile)
if err != nil {
return err
}
v.htmlRecoveryTempl, err = ht.ParseFiles(v.RecoveryTemplFile)
v.htmlResetTempl, err = ht.ParseFiles(v.ResetTemplFile)
if err != nil {
return err
}
Expand Down Expand Up @@ -167,18 +167,18 @@ func (v *validator) Request(user t.Uid, email, lang string, resp string) error {
})
}

// Recover sends a message with instructions for recovery of an authentication secret.
func (v *validator) Recover(email, scheme, lang string, tmpToken []byte) error {
// ResetSecret sends a message with instructions for resetting an authentication secret.
func (v *validator) ResetSecret(email, scheme, lang string, tmpToken []byte) error {
body := new(bytes.Buffer)
if err := v.htmlRecoveryTempl.Execute(body, map[string]interface{}{
if err := v.htmlResetTempl.Execute(body, map[string]interface{}{
"Token": tmpToken,
"Scheme": scheme,
"HostUrl": v.HostUrl}); err != nil {
return err
}

// Send email without blocking. Email sending may take long time.
go v.send(email, v.RecoverySubject, string(body.Bytes()))
go v.send(email, v.ResetSubject, string(body.Bytes()))

return nil
}
Expand Down
6 changes: 3 additions & 3 deletions server/validate/tel/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ func (*validator) Request(user t.Uid, cred, lang string, resp string) error {
return nil
}

// Recover sends a message with instructions for recovery of an authentication secret.
func (*validator) Recover(cred, scheme, lang string, tmpToken []byte) error {
// TODO: send recovery email
// ResetSecret sends a message with instructions for resetting an authentication secret.
func (*validator) ResetSecret(cred, scheme, lang string, tmpToken []byte) error {
// TODO: send SMS with rest instructions.
return nil
}

Expand Down
6 changes: 3 additions & 3 deletions server/validate/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ type Validator interface {
// resp: optional response if user already has it (i.e. captcha/recaptcha).
Request(user t.Uid, cred, lang string, resp string) error

// Recover sends a message with instructions for recovery of an authentication secret.
// ResetSecret sends a message with instructions for resetting an authentication secret.
// cred: address to use for the message.
// scheme: authentication scheme being recovered.
// scheme: authentication scheme being reset.
// lang: human language as reported in the session.
// tmpToken: temporary authentication token
Recover(cred, scheme, lang string, tmpToken []byte) error
ResetSecret(cred, scheme, lang string, tmpToken []byte) error

// Check checks validity of user response.
Check(user t.Uid, resp string) error
Expand Down

0 comments on commit 1870fff

Please sign in to comment.