Send a request for confirmation to the user: makes a record in DB and nothing else.
(user t.Uid, email, lang, resp string, tmpToken []byte)
| 253 | |
| 254 | // Send a request for confirmation to the user: makes a record in DB and nothing else. |
| 255 | func (v *validator) Request(user t.Uid, email, lang, resp string, tmpToken []byte) (bool, error) { |
| 256 | // Email validator cannot accept an immediate response. |
| 257 | if resp != "" { |
| 258 | return false, t.ErrFailed |
| 259 | } |
| 260 | |
| 261 | // Normalize email to make sure Unicode case collisions don't lead to security problems. |
| 262 | email = strings.ToLower(email) |
| 263 | |
| 264 | token := make([]byte, base64.StdEncoding.EncodedLen(len(tmpToken))) |
| 265 | base64.StdEncoding.Encode(token, tmpToken) |
| 266 | |
| 267 | // Generate expected response as a random numeric string between 0 and 999999. |
| 268 | code, err := crand.Int(crand.Reader, v.maxCodeValue) |
| 269 | if err != nil { |
| 270 | return false, err |
| 271 | } |
| 272 | resp = strconv.FormatInt(code.Int64(), 10) |
| 273 | resp = strings.Repeat("0", v.CodeLength-len(resp)) + resp |
| 274 | |
| 275 | var template *textt.Template |
| 276 | if v.langMatcher != nil { |
| 277 | // Find the template for the requested language. |
| 278 | // Make sure the language tag is standardized. Matcher is a bit dumber than Parse(). |
| 279 | normalized, _ := i18n.Parse(lang) |
| 280 | // The matched tag is usually not in the list of available languages (e.g. es_ES -> es-u-rg-eszzzz). |
| 281 | // Use index to find the template instead of tag. |
| 282 | _, idx := i18n.MatchStrings(v.langMatcher, normalized.String()) |
| 283 | template = v.validationTempl[idx] |
| 284 | } else { |
| 285 | template = v.validationTempl[0] |
| 286 | } |
| 287 | |
| 288 | content, err := validate.ExecuteTemplate(template, templateParts, map[string]any{ |
| 289 | "Token": url.QueryEscape(string(token)), |
| 290 | "Code": resp, |
| 291 | "HostUrl": v.HostUrl}) |
| 292 | if err != nil { |
| 293 | return false, err |
| 294 | } |
| 295 | |
| 296 | // Create or update validation record in DB. |
| 297 | isNew, err := store.Users.UpsertCred(&t.Credential{ |
| 298 | User: user.String(), |
| 299 | Method: validatorName, |
| 300 | Value: email, |
| 301 | Resp: resp}) |
| 302 | if err != nil { |
| 303 | return false, err |
| 304 | } |
| 305 | |
| 306 | // Send email without blocking. Email sending may take long time. |
| 307 | go v.send(email, content) |
| 308 | |
| 309 | return isNew, nil |
| 310 | } |
| 311 | |
| 312 | // ResetSecret sends a message with instructions for resetting an authentication secret. |
nothing calls this directly
no test coverage detected