mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-20 04:14:49 +02:00
user gomail and new activate account email tpl
- #1496: fallback plain text - #1002: add date header - #913: fix encoding of header
This commit is contained in:
1 parent
e75fd2f783
commit
373731f5e8
16 files changed
+187
-302
No files matched your search
@@ -33,6 +33,7 @@ github.com/russross/blackfriday = commit:8cec3a854e
|
||||
github.com/shurcooL/sanitized_anchor_name = commit:244f5ac324
|
||||
golang.org/x/net =
|
||||
golang.org/x/text =
|
||||
gopkg.in/gomail.v2 =
|
||||
gopkg.in/ini.v1 = commit:463307112d
|
||||
gopkg.in/redis.v2 = commit:e617904962
|
||||
|
||||
|
||||
@@ -160,6 +160,11 @@ invalid_code = Sorry, your confirmation code has expired or not valid.
|
||||
reset_password_helper = Click here to reset your password
|
||||
password_too_short = Password length cannot be less then 6.
|
||||
|
||||
[mail]
|
||||
register_success = Register success, Welcome
|
||||
activate_account = Please activate your account
|
||||
activate_email = Verify your e-mail address
|
||||
|
||||
[modal]
|
||||
yes = Yes
|
||||
no = No
|
||||
|
||||
@@ -133,6 +133,22 @@ func (u *User) HomeLink() string {
|
||||
return setting.AppSubUrl + "/" + u.Name
|
||||
}
|
||||
|
||||
// GenerateEmailActivateCode generates an activate code based on user information and given e-mail.
|
||||
func (u *User) GenerateEmailActivateCode(email string) string {
|
||||
code := base.CreateTimeLimitCode(
|
||||
com.ToStr(u.Id)+email+u.LowerName+u.Passwd+u.Rands,
|
||||
setting.Service.ActiveCodeLives, nil)
|
||||
|
||||
// Add tail hex username
|
||||
code += hex.EncodeToString([]byte(u.LowerName))
|
||||
return code
|
||||
}
|
||||
|
||||
// GenerateActivateCode generates an activate code based on user information.
|
||||
func (u *User) GenerateActivateCode() string {
|
||||
return u.GenerateEmailActivateCode(u.Email)
|
||||
}
|
||||
|
||||
// CustomAvatarPath returns user custom avatar file path.
|
||||
func (u *User) CustomAvatarPath() string {
|
||||
return filepath.Join(setting.AvatarUploadPath, com.ToStr(u.Id))
|
||||
|
||||
@@ -4364,7 +4364,7 @@ func confLocaleLocale_deDeIni() (*asset, error) {
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _confLocaleLocale_enUsIni = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xc4\xbd\xeb\x72\xdc\xc8\x8e\x27\xfe\x9d\x4f\xc1\xf6\x84\xff\xee\x8e\x90\xcb\xd1\xdd\xff\xbd\x44\x47\xdb\xbd\xb2\xd4\xbe\xcc\x58\x96\xc6\x52\x9f\xb3\x67\x1d\x8e\x6a\x56\x91\xaa\xe2\x71\x15\x59\x4d\xb2\x2c\xeb\x4c\x4c\xc4\xbe\xc6\xbe\xde\x3e\xc9\x02\x3f\x00\x79\x23\x4b\xb2\xcf\x99\xd8\xfd\x22\xb1\x32\x91\x37\x24\x12\x09\x20\x91\xc8\x62\xb7\x9b\x97\x55\xbf\xcc\x9f\xe6\xc7\xf9\xae\xa8\x9b\x4d\xd5\xf7\x79\x5f\x6d\xae\x1f\xaf\xdb\x7e\xa8\xca\xfc\x65\x3d\xd0\xef\xee\x53\xbd\xac\xb2\x6c\xdd\x6e\x2b\x02\x7d\x45\xff\xb2\xb2\xe8\xd7\x8b\xb6\xe8\x4a\x4a\x38\xb5\xef\xac\xfa\xbc\xdb\xb4\x1d\x03\xfd\x2a\x5f\xd9\xba\xda\xec\xb8\x0c\xfd\xcb\xfa\x7a\xd5\xcc\xeb\x86\x7e\x5e\xd2\x57\xfe\xba\xc9\xfa\x76\x59\x17\x9b\x79\x90\x81\x04\xcb\xff\x29\xff\xa1\x29\xf3\xcb\xa1\xda\xe5\x3f\xf7\xdb\x62\xb3\x79\x56\xf4\x28\x32\x54\x79\xb1\x5c\xb6\xfb\x66\xf8\xf9\x89\x64\x48\xe5\xed\x7e\xb0\xda\xcf\xf7\x83\xa4\xed\x77\x96\xf4\xdb\x2e\xeb\xaa\x55\x4d\x03\xeb\x28\xe9\x9d\x7e\x66\x37\xd5\xa2\xaf\x07\xee\xf4\x9f\xe5\x2b\xfb\x54\x75\x7d\xdd\x72\x7f\xfe\x24\x5f\xd9\xae\x58\x31\xc0\x05\xfd\xcb\x86\x6a\xbb\xdb\x14\x28\x70\xa5\x9f\xd9\xa6\x68\x56\x7b\x81\x79\xa3\x9f\xd9\xb2\xab\x28\x6b\xde\x54\x37\x94\x7a\x82\x1f\xb3\xd9\x2c\xdb\x13\x3e\xe7\xbb\xae\xbd\xae\x37\xd5\xbc\x68\xca\xf9\x56\x30\xf6\x1b\xa5\xe7\x9a\x9e\x53\x7a\xce\xe9\x18\x42\x55\x12\x72\xe6\x45\xaf\xe3\xa0\x69\x21\x5c\x15\x7d\x86\xaa\x9a\x62\x6b\xa5\xf9\x33\xab\xb6\x45\xbd\xe1\x09\x78\xcc\x1f\xd4\xf1\xbe\xbf\x69\x31\x4d\x17\xfa\x49\x48\x98\x0f\xb7\xbb\x0a\x38\x78\x7c\x45\x5f\xd9\xb2\xd8\x0d\xcb\x75\xc1\xfd\x94\xaf\x8c\x80\x76\x2d\x21\xa3\xed\x6e\x01\x67\x3f\xb2\xb6\x5b\x15\x4d\xfd\xb7\x62\x10\x04\x9d\x07\x3f\xb3\x6d\xdd\x75\x2d\xe3\xf6\x0c\x1f\x19\x0d\x7d\xce\xf5\x50\xca\x5b\xc2\x42\x50\x0b\xe7\x6c\xeb\x55\x27\x68\xe4\xcc\x33\xfc\xe2\x5a\x38\xef\xba\xed\x3e\x6a\xc6\x0b\xfe\x4c\x8a\x52\x27\x34\x37\x6e\xbf\x68\x08\xf1\x9a\x7b\x86\x1f\x11\x40\x9f\x15\xe5\x96\x50\xb9\x2b\x9a\x8a\x71\x74\xcc\xbf\x08\x2f\xf4\x2b\x53\x7a\x9a\xf7\xd5\x30\xd4\xcd\x8a\x91\x7d\x2c\x49\xf9\xa5\x26\x65\x41\x9e\x4b\xbb\x6d\xf7\x6e\x3a\x29\xfd\x2f\xf4\x33\xbf\x90\x9f\x92\x17\x14\x42\xa6\x2b\xc9\x23\xe9\xe7\xd7\x55\x55\xca\x58\xfa\xfc\x05\x7d\x67\xbb\xfd\x66\x43\x58\xfb\x63\x5f\xf5\x03\x17\xba\xa0\xdf\x34\x7e\xf9\x9d\xd5\x7d\x4f\x1f\x94\xfc\x1a\x1f\x19\x4d\x5d\xb3\xc4\x60\x4e\xf0\x91\x65\xef\xfb\xaa\xe8\x96\xeb\x0f\x99\xfc\x47\x5f\xf9\x83\x69\xef\xd0\xa4\x32\x21\x29\x11\x49\x0b\xd6\x40\xb6\x6c\x4b\xfe\x71\x42\xff\xa8\xea\xba\xe9\x07\x5a\x6d\x1f\x32\xfd\x60\x30\xf9\x92\x09\x18\xea\x01\x58\xd0\x44\x2c\xdd\x9e\x67\x30\x7f\x51\x77\xfd\xf0\x78\xa8\x89\x58\xdf\xed\x9b\x8c\xc7\x47\x2b\x6d\x5e\x2e\x8c\x01\xbd\x6c\x09\x45\x48\xee\x68\x7c\x67\xb7\x97\xff\xfa\xe6\x28\xbf\x20\x2e\xb4\xea\x2a\x7c\xd3\x1f\x2a\xf1\x63\x4e\x95\x5d\xd5\xa7\xcf\x67\x19\x95\xb5\xf6\x4e\x8b\xa1\x58\x14\x7d\xe5\x91\xcb\x99\x42\xe3\x2e\x0f\x94\xce\x7c\x0d\x3c\xac\x1f\xa2\x51\x4f\xad\x13\xaa\x43\x57\x97\xab\xe3\x2d\x2f\x31\x4a\x67\xb6\x86\xc2\x17\x9b\x8a\xd3\xa9\xaa\xfc\xf5\xdb\xb7\xe7\xa7\xcf\xf3\xaa\x59\xd5\x4d\x95\xdf\xd4\xc3\x3a\xdf\x0f\xd7\xff\x75\xbe\xaa\x9a\xaa\x23\x2e\xb7\xac\x73\x5a\x59\x1d\xd1\x43\x4e\xe4\x2d\x43\x9c\x65\x7d\xbf\x21\x0e\x00\x24\x5f\x5e\xbe\xc9\xcf\x18\xd1\xbb\x62\x58\xa3\x23\xc3\x3a\xeb\xff\xd8\x30\xa2\x5c\x83\x57\xeb\x2a\x07\xad\x01\xa8\xbd\x4e\xf1\x92\x97\xda\xd7\x59\x56\x75\xdd\x9c\x18\xd4\x70\xcb\x68\xd6\x3a\x0f\x41\x4b\x75\x44\x4c\x4d\x3b\xe4\x8b\x2a\x47\x39\xa9\xa2\x6e\x3e\x15\x9b\xba\x24\x64\x7b\x84\xc4\x65\x91\x58\xb6\x34\x6f\x5c\x9a\x26\xbe\xbd\xc1\x50\x8b\x25\xf1\xd7\x3e\x7f\x30\x7b\x00\x86\xf6\xe0\xf1\x83\x59\xd6\xb4\x73\x59\x84\xcc\xfa\xca\xba\x2f\x16\xc4\x06\x85\x2d\x77\xc6\x54\x68\x9d\x58\x57\x14\x22\x8f\x20\x18\xb7\xcc\xea\xc1\x61\x69\xba\xa9\xf6\x1c\x95\xda\xae\x10\x8e\xdd\x96\xbc\x9b\x5f\x59\xf5\x2e\x61\x34\xe6\xcc\x26\xcc\xa8\xeb\x78\xb7\xdb\xd4\x4b\x69\xfa\xa5\xe4\x79\x42\xe3\x3d\x54\x91\x12\xc2\x81\x50\x2c\x2f\x20\x17\xea\x35\x73\x85\x3c\x62\xa3\x28\xbf\xae\x68\x1b\x58\xef\x57\xc2\xfc\x37\xed\xbe\xfc\x06\xeb\xd5\x66\xce\x2f\xd7\xfc\x5d\x4b\x1d\x06\x75\x38\x00\xdf\xc4\x31\xad\x3b\xde\xb6\xbb\x6a\xdb\x0e\x8c\x38\x2d\x56\xd3\xf4\xdc\xd4\x94\x49\x23\xed\x8b\x4f\xc4\x75\x86\x36\x1f\xd6\x75\x4f\x38\xee\xaa\x25\x57\x4c\x0c\x62\x4f\x1b\xa6\x2c\x0b\x5a\xa6\xb2\x34\x2c\x2d\xa6\x41\x40\x6d\xf7\xb4\x9a\xd6\x54\x19\x23\x9e\x65\x07\xaa\x72\xaa\x9f\x18\x12\xd5\x83\x55\x4e\x2b\xb7\xa5\xbd\x89\x27\xfa\x14\x1f\xfa\x3b\xac\x9f\x7a\x55\x5c\x5f\x53\xaf\x7a\x5a\x15\xaf\xf2\xe5\xa6\xa5\x25\xf5\xdb\xbb\x37\x3d\x2f\x98\xf5\x7c\xd7\x76\xd8\xe8\x29\xeb\x82\x3e\x5d\x5a\x80\x68\x86\x68\xf6\xdb\x05\xfd\xba\x59\xd7\xc4\x07\x81\x76\x2e\xc1\xf2\x0c\xa5\x52\x13\xfb\x9e\xa6\xf0\x28\xa7\x25\x4c\x23\x20\x94\x81\x00\x78\x0c\x46\x75\x0c\x7e\x4d\x34\xb6\xef\x68\x39\xad\x87\x61\x67\x2d\xbf\xba\xba\xba\x90\xa6\x5d\xea\x5d\x6d\x17\x01\x65\x60\x0e\x36\x2c\x7a\x34\x79\xdb\xcc\x40\x24\xfb\x6e\x93\xd0\x0f\x8d\xd5\x72\x0e\xe0\x85\xbb\xf0\x84\xff\x5c\x7a\xf4\x00\xcf\x3d\xc9\x67\x37\xaLine truncated
|
||||
var _confLocaleLocale_enUsIni = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xc4\xbd\xeb\x72\xdc\xc8\x8e\x27\xfe\x9d\x4f\xc1\xf6\x84\xff\xee\x8e\x90\xcb\xd1\xdd\xff\xbd\x44\x47\xdb\xbd\xb2\xd4\xbe\xcc\x58\x96\xc6\x52\x9f\xb3\x67\x1d\x8e\x6a\x56\x91\xaa\xe2\x71\x15\x59\x4d\xb2\x2c\xeb\x4c\x4c\xc4\xbe\xc6\xbe\xde\x3e\xc9\x02\x3f\x00\x79\x23\x4b\xb2\xcf\x99\xd8\xfd\x22\xb1\x32\x91\x37\x24\x12\x09\x20\x91\xc8\x62\xb7\x9b\x97\x55\xbf\xcc\x9f\xe6\xc7\xf9\xae\xa8\x9b\x4d\xd5\xf7\x79\x5f\x6d\xae\x1f\xaf\xdb\x7e\xa8\xca\xfc\x65\x3d\xd0\xef\xee\x53\xbd\xac\xb2\x6c\xdd\x6e\x2b\x02\x7d\x45\xff\xb2\xb2\xe8\xd7\x8b\xb6\xe8\x4a\x4a\x38\xb5\xef\xac\xfa\xbc\xdb\xb4\x1d\x03\xfd\x2a\x5f\xd9\xba\xda\xec\xb8\x0c\xfd\xcb\xfa\x7a\xd5\xcc\xeb\x86\x7e\x5e\xd2\x57\xfe\xba\xc9\xfa\x76\x59\x17\x9b\x79\x90\x81\x04\xcb\xff\x29\xff\xa1\x29\xf3\xcb\xa1\xda\xe5\x3f\xf7\xdb\x62\xb3\x79\x56\xf4\x28\x32\x54\x79\xb1\x5c\xb6\xfb\x66\xf8\xf9\x89\x64\x48\xe5\xed\x7e\xb0\xda\xcf\xf7\x83\xa4\xed\x77\x96\xf4\xdb\x2e\xeb\xaa\x55\x4d\x03\xeb\x28\xe9\x9d\x7e\x66\x37\xd5\xa2\xaf\x07\xee\xf4\x9f\xe5\x2b\xfb\x54\x75\x7d\xdd\x72\x7f\xfe\x24\x5f\xd9\xae\x58\x31\xc0\x05\xfd\xcb\x86\x6a\xbb\xdb\x14\x28\x70\xa5\x9f\xd9\xa6\x68\x56\x7b\x81\x79\xa3\x9f\xd9\xb2\xab\x28\x6b\xde\x54\x37\x94\x7a\x82\x1f\xb3\xd9\x2c\xdb\x13\x3e\xe7\xbb\xae\xbd\xae\x37\xd5\xbc\x68\xca\xf9\x56\x30\xf6\x1b\xa5\xe7\x9a\x9e\x53\x7a\xce\xe9\x18\x42\x55\x12\x72\xe6\x45\xaf\xe3\xa0\x69\x21\x5c\x15\x7d\x86\xaa\x9a\x62\x6b\xa5\xf9\x33\xab\xb6\x45\xbd\xe1\x09\x78\xcc\x1f\xd4\xf1\xbe\xbf\x69\x31\x4d\x17\xfa\x49\x48\x98\x0f\xb7\xbb\x0a\x38\x78\x7c\x45\x5f\xd9\xb2\xd8\x0d\xcb\x75\xc1\xfd\x94\xaf\x8c\x80\x76\x2d\x21\xa3\xed\x6e\x01\x67\x3f\xb2\xb6\x5b\x15\x4d\xfd\xb7\x62\x10\x04\x9d\x07\x3f\xb3\x6d\xdd\x75\x2d\xe3\xf6\x0c\x1f\x19\x0d\x7d\xce\xf5\x50\xca\x5b\xc2\x42\x50\x0b\xe7\x6c\xeb\x55\x27\x68\xe4\xcc\x33\xfc\xe2\x5a\x38\xef\xba\xed\x3e\x6a\xc6\x0b\xfe\x4c\x8a\x52\x27\x34\x37\x6e\xbf\x68\x08\xf1\x9a\x7b\x86\x1f\x11\x40\x9f\x15\xe5\x96\x50\xb9\x2b\x9a\x8a\x71\x74\xcc\xbf\x08\x2f\xf4\x2b\x53\x7a\x9a\xf7\xd5\x30\xd4\xcd\x8a\x91\x7d\x2c\x49\xf9\xa5\x26\x65\x41\x9e\x4b\xbb\x6d\xf7\x6e\x3a\x29\xfd\x2f\xf4\x33\xbf\x90\x9f\x92\x17\x14\x42\xa6\x2b\xc9\x23\xe9\xe7\xd7\x55\x55\xca\x58\xfa\xfc\x05\x7d\x67\xbb\xfd\x66\x43\x58\xfb\x63\x5f\xf5\x03\x17\xba\xa0\xdf\x34\x7e\xf9\x9d\xd5\x7d\x4f\x1f\x94\xfc\x1a\x1f\x19\x4d\x5d\xb3\xc4\x60\x4e\xf0\x91\x65\xef\xfb\xaa\xe8\x96\xeb\x0f\x99\xfc\x47\x5f\xf9\x83\x69\xef\xd0\xa4\x32\x21\x29\x11\x49\x0b\xd6\x40\xb6\x6c\x4b\xfe\x71\x42\xff\xa8\xea\xba\xe9\x07\x5a\x6d\x1f\x32\xfd\x60\x30\xf9\x92\x09\x18\xea\x01\x58\xd0\x44\x2c\xdd\x9e\x67\x30\x7f\x51\x77\xfd\xf0\x78\xa8\x89\x58\xdf\xed\x9b\x8c\xc7\x47\x2b\x6d\x5e\x2e\x8c\x01\xbd\x6c\x09\x45\x48\xee\x68\x7c\x67\xb7\x97\xff\xfa\xe6\x28\xbf\x20\x2e\xb4\xea\x2a\x7c\xd3\x1f\x2a\xf1\x63\x4e\x95\x5d\xd5\xa7\xcf\x67\x19\x95\xb5\xf6\x4e\x8b\xa1\x58\x14\x7d\xe5\x91\xcb\x99\x42\xe3\x2e\x0f\x94\xce\x7c\x0d\x3c\xac\x1f\xa2\x51\x4f\xad\x13\xaa\x43\x57\x97\xab\xe3\x2d\x2f\x31\x4a\x67\xb6\x86\xc2\x17\x9b\x8a\xd3\xa9\xaa\xfc\xf5\xdb\xb7\xe7\xa7\xcf\xf3\xaa\x59\xd5\x4d\x95\xdf\xd4\xc3\x3a\xdf\x0f\xd7\xff\x75\xbe\xaa\x9a\xaa\x23\x2e\xb7\xac\x73\x5a\x59\x1d\xd1\x43\x4e\xe4\x2d\x43\x9c\x65\x7d\xbf\x21\x0e\x00\x24\x5f\x5e\xbe\xc9\xcf\x18\xd1\xbb\x62\x58\xa3\x23\xc3\x3a\xeb\xff\xd8\x30\xa2\x5c\x83\x57\xeb\x2a\x07\xad\x01\xa8\xbd\x4e\xf1\x92\x97\xda\xd7\x59\x56\x75\xdd\x9c\x18\xd4\x70\xcb\x68\xd6\x3a\x0f\x41\x4b\x75\x44\x4c\x4d\x3b\xe4\x8b\x2a\x47\x39\xa9\xa2\x6e\x3e\x15\x9b\xba\x24\x64\x7b\x84\xc4\x65\x91\x58\xb6\x34\x6f\x5c\x9a\x26\xbe\xbd\xc1\x50\x8b\x25\xf1\xd7\x3e\x7f\x30\x7b\x00\x86\xf6\xe0\xf1\x83\x59\xd6\xb4\x73\x59\x84\xcc\xfa\xca\xba\x2f\x16\xc4\x06\x85\x2d\x77\xc6\x54\x68\x9d\x58\x57\x14\x22\x8f\x20\x18\xb7\xcc\xea\xc1\x61\x69\xba\xa9\xf6\x1c\x95\xda\xae\x10\x8e\xdd\x96\xbc\x9b\x5f\x59\xf5\x2e\x61\x34\xe6\xcc\x26\xcc\xa8\xeb\x78\xb7\xdb\xd4\x4b\x69\xfa\xa5\xe4\x79\x42\xe3\x3d\x54\x91\x12\xc2\x81\x50\x2c\x2f\x20\x17\xea\x35\x73\x85\x3c\x62\xa3\x28\xbf\xae\x68\x1b\x58\xef\x57\xc2\xfc\x37\xed\xbe\xfc\x06\xeb\xd5\x66\xce\x2f\xd7\xfc\x5d\x4b\x1d\x06\x75\x38\x00\xdf\xc4\x31\xad\x3b\xde\xb6\xbb\x6a\xdb\x0e\x8c\x38\x2d\x56\xd3\xf4\xdc\xd4\x94\x49\x23\xed\x8b\x4f\xc4\x75\x86\x36\x1f\xd6\x75\x4f\x38\xee\xaa\x25\x57\x4c\x0c\x62\x4f\x1b\xa6\x2c\x0b\x5a\xa6\xb2\x34\x2c\x2d\xa6\x41\x40\x6d\xf7\xb4\x9a\xd6\x54\x19\x23\x9e\x65\x07\xaa\x72\xaa\x9f\x18\x12\xd5\x83\x55\x4e\x2b\xb7\xa5\xbd\x89\x27\xfa\x14\x1f\xfa\x3b\xac\x9f\x7a\x55\x5c\x5f\x53\xaf\x7a\x5a\x15\xaf\xf2\xe5\xa6\xa5\x25\xf5\xdb\xbb\x37\x3d\x2f\x98\xf5\x7c\xd7\x76\xd8\xe8\x29\xeb\x82\x3e\x5d\x5a\x80\x68\x86\x68\xf6\xdb\x05\xfd\xba\x59\xd7\xc4\x07\x81\x76\x2e\xc1\xf2\x0c\xa5\x52\x13\xfb\x9e\xa6\xf0\x28\xa7\x25\x4c\x23\x20\x94\x81\x00\x78\x0c\x46\x75\x0c\x7e\x4d\x34\xb6\xef\x68\x39\xad\x87\x61\x67\x2d\xbf\xba\xba\xba\x90\xa6\x5d\xea\x5d\x6d\x17\x01\x65\x60\x0e\x36\x2c\x7a\x34\x79\xdb\xcc\x40\x24\xfb\x6e\x93\xd0\x0f\x8d\xd5\x72\x0e\xe0\x85\xbb\xf0\x84\xff\x5c\x7a\xf4\x00\xcf\x3d\xc9\x67\x37\xaLine truncated
|
||||
|
||||
func confLocaleLocale_enUsIniBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
@@ -4379,7 +4379,7 @@ func confLocaleLocale_enUsIni() (*asset, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "conf/locale/locale_en-US.ini", size: 43577, mode: os.FileMode(420), modTime: time.Unix(1442448353, 0)}
|
||||
info := bindataFileInfo{name: "conf/locale/locale_en-US.ini", size: 43722, mode: os.FileMode(420), modTime: time.Unix(1442467863, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
+32
-94
@@ -5,12 +5,10 @@
|
||||
package mailer
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/Unknwon/macaron"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
@@ -20,26 +18,16 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
AUTH_ACTIVE base.TplName = "mail/auth/active"
|
||||
AUTH_ACTIVATE_EMAIL base.TplName = "mail/auth/activate_email"
|
||||
AUTH_REGISTER_SUCCESS base.TplName = "mail/auth/register_success"
|
||||
AUTH_ACTIVATE base.TplName = "mail/auth/activate"
|
||||
AUTH_ACTIVATE_EMAIL base.TplName = "mail/auth/activate_email"
|
||||
AUTH_RESET_PASSWORD base.TplName = "mail/auth/reset_passwd"
|
||||
|
||||
NOTIFY_COLLABORATOR base.TplName = "mail/notify/collaborator"
|
||||
NOTIFY_MENTION base.TplName = "mail/notify/mention"
|
||||
)
|
||||
|
||||
// Create New mail message use MailFrom and MailUser
|
||||
func NewMailMessageFrom(To []string, from, subject, body string) Message {
|
||||
return NewHtmlMessage(To, from, subject, body)
|
||||
}
|
||||
|
||||
// Create New mail message use MailFrom and MailUser
|
||||
func NewMailMessage(To []string, subject, body string) Message {
|
||||
return NewMailMessageFrom(To, setting.MailService.From, subject, body)
|
||||
}
|
||||
|
||||
func GetMailTmplData(u *models.User) map[interface{}]interface{} {
|
||||
func ComposeTplData(u *models.User) map[interface{}]interface{} {
|
||||
data := make(map[interface{}]interface{}, 10)
|
||||
data["AppName"] = setting.AppName
|
||||
data["AppVer"] = setting.AppVer
|
||||
@@ -52,95 +40,45 @@ func GetMailTmplData(u *models.User) map[interface{}]interface{} {
|
||||
return data
|
||||
}
|
||||
|
||||
// create a time limit code for user active
|
||||
func CreateUserActiveCode(u *models.User, startInf interface{}) string {
|
||||
minutes := setting.Service.ActiveCodeLives
|
||||
data := com.ToStr(u.Id) + u.Email + u.LowerName + u.Passwd + u.Rands
|
||||
code := base.CreateTimeLimitCode(data, minutes, startInf)
|
||||
|
||||
// add tail hex username
|
||||
code += hex.EncodeToString([]byte(u.LowerName))
|
||||
return code
|
||||
}
|
||||
|
||||
// create a time limit code for user active
|
||||
func CreateUserEmailActivateCode(u *models.User, e *models.EmailAddress, startInf interface{}) string {
|
||||
minutes := setting.Service.ActiveCodeLives
|
||||
data := com.ToStr(u.Id) + e.Email + u.LowerName + u.Passwd + u.Rands
|
||||
code := base.CreateTimeLimitCode(data, minutes, startInf)
|
||||
|
||||
// add tail hex username
|
||||
code += hex.EncodeToString([]byte(u.LowerName))
|
||||
return code
|
||||
}
|
||||
|
||||
// Send user register mail with active code
|
||||
func SendRegisterMail(r macaron.Render, u *models.User) {
|
||||
code := CreateUserActiveCode(u, nil)
|
||||
subject := "Register success, Welcome"
|
||||
|
||||
data := GetMailTmplData(u)
|
||||
data["Code"] = code
|
||||
body, err := r.HTMLString(string(AUTH_REGISTER_SUCCESS), data)
|
||||
func SendActivateAccountMail(c *macaron.Context, u *models.User) {
|
||||
data := ComposeTplData(u)
|
||||
data["Code"] = u.GenerateActivateCode()
|
||||
body, err := c.HTMLString(string(AUTH_ACTIVATE), data)
|
||||
if err != nil {
|
||||
log.Error(4, "mail.SendRegisterMail(fail to render): %v", err)
|
||||
log.Error(4, "HTMLString: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
msg := NewMailMessage([]string{u.Email}, subject, body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, send register mail", u.Id)
|
||||
msg := NewMessage([]string{u.Email}, c.Tr("mail.activate_account"), body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, activate account", u.Id)
|
||||
|
||||
SendAsync(&msg)
|
||||
SendAsync(msg)
|
||||
}
|
||||
|
||||
// Send email verify active email.
|
||||
func SendActiveMail(r macaron.Render, u *models.User) {
|
||||
code := CreateUserActiveCode(u, nil)
|
||||
|
||||
subject := "Verify your e-mail address"
|
||||
|
||||
data := GetMailTmplData(u)
|
||||
data["Code"] = code
|
||||
body, err := r.HTMLString(string(AUTH_ACTIVE), data)
|
||||
if err != nil {
|
||||
log.Error(4, "mail.SendActiveMail(fail to render): %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
msg := NewMailMessage([]string{u.Email}, subject, body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, send active mail", u.Id)
|
||||
|
||||
SendAsync(&msg)
|
||||
}
|
||||
|
||||
// Send email to verify secondary email.
|
||||
func SendActivateEmail(r macaron.Render, user *models.User, email *models.EmailAddress) {
|
||||
code := CreateUserEmailActivateCode(user, email, nil)
|
||||
|
||||
subject := "Verify your e-mail address"
|
||||
|
||||
data := GetMailTmplData(user)
|
||||
data["Code"] = code
|
||||
// SendActivateAccountMail sends confirmation e-mail.
|
||||
func SendActivateEmailMail(c *macaron.Context, u *models.User, email *models.EmailAddress) {
|
||||
data := ComposeTplData(u)
|
||||
data["Code"] = u.GenerateEmailActivateCode(email.Email)
|
||||
data["Email"] = email.Email
|
||||
body, err := r.HTMLString(string(AUTH_ACTIVATE_EMAIL), data)
|
||||
body, err := c.HTMLString(string(AUTH_ACTIVATE_EMAIL), data)
|
||||
if err != nil {
|
||||
log.Error(4, "mail.SendActiveMail(fail to render): %v", err)
|
||||
log.Error(4, "HTMLString: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
msg := NewMailMessage([]string{email.Email}, subject, body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, send activate email to %s", user.Id, email.Email)
|
||||
msg := NewMessage([]string{email.Email}, c.Tr("mail.activate_email"), body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, activate email: %s", u.Id, email.Email)
|
||||
|
||||
SendAsync(&msg)
|
||||
SendAsync(msg)
|
||||
}
|
||||
|
||||
// Send reset password email.
|
||||
func SendResetPasswdMail(r macaron.Render, u *models.User) {
|
||||
code := CreateUserActiveCode(u, nil)
|
||||
code := u.GenerateActivateCode()
|
||||
|
||||
subject := "Reset your password"
|
||||
|
||||
data := GetMailTmplData(u)
|
||||
data := ComposeTplData(u)
|
||||
data["Code"] = code
|
||||
body, err := r.HTMLString(string(AUTH_RESET_PASSWORD), data)
|
||||
if err != nil {
|
||||
@@ -148,10 +86,10 @@ func SendResetPasswdMail(r macaron.Render, u *models.User) {
|
||||
return
|
||||
}
|
||||
|
||||
msg := NewMailMessage([]string{u.Email}, subject, body)
|
||||
msg := NewMessage([]string{u.Email}, subject, body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, send reset password email", u.Id)
|
||||
|
||||
SendAsync(&msg)
|
||||
SendAsync(msg)
|
||||
}
|
||||
|
||||
// SendIssueNotifyMail sends mail notification of all watchers of repository.
|
||||
@@ -182,9 +120,9 @@ func SendIssueNotifyMail(u, owner *models.User, repo *models.Repository, issue *
|
||||
content := fmt.Sprintf("%s<br>-<br> <a href=\"%s%s/%s/issues/%d\">View it on Gogs</a>.",
|
||||
base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name),
|
||||
setting.AppUrl, owner.Name, repo.Name, issue.Index)
|
||||
msg := NewMailMessageFrom(tos, u.Email, subject, content)
|
||||
msg := NewMessageFrom(tos, u.Email, subject, content)
|
||||
msg.Info = fmt.Sprintf("Subject: %s, send issue notify emails", subject)
|
||||
SendAsync(&msg)
|
||||
SendAsync(msg)
|
||||
return tos, nil
|
||||
}
|
||||
|
||||
@@ -198,7 +136,7 @@ func SendIssueMentionMail(r macaron.Render, u, owner *models.User,
|
||||
|
||||
subject := fmt.Sprintf("[%s] %s (#%d)", repo.Name, issue.Name, issue.Index)
|
||||
|
||||
data := GetMailTmplData(nil)
|
||||
data := ComposeTplData(nil)
|
||||
data["IssueLink"] = fmt.Sprintf("%s/%s/issues/%d", owner.Name, repo.Name, issue.Index)
|
||||
data["Subject"] = subject
|
||||
|
||||
@@ -207,9 +145,9 @@ func SendIssueMentionMail(r macaron.Render, u, owner *models.User,
|
||||
return fmt.Errorf("mail.SendIssueMentionMail(fail to render): %v", err)
|
||||
}
|
||||
|
||||
msg := NewMailMessageFrom(tos, u.Email, subject, body)
|
||||
msg := NewMessageFrom(tos, u.Email, subject, body)
|
||||
msg.Info = fmt.Sprintf("Subject: %s, send issue mention emails", subject)
|
||||
SendAsync(&msg)
|
||||
SendAsync(msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -219,7 +157,7 @@ func SendCollaboratorMail(r macaron.Render, u, owner *models.User,
|
||||
|
||||
subject := fmt.Sprintf("%s added you to %s", owner.Name, repo.Name)
|
||||
|
||||
data := GetMailTmplData(nil)
|
||||
data := ComposeTplData(nil)
|
||||
data["RepoLink"] = path.Join(owner.Name, repo.Name)
|
||||
data["Subject"] = subject
|
||||
|
||||
@@ -228,9 +166,9 @@ func SendCollaboratorMail(r macaron.Render, u, owner *models.User,
|
||||
return fmt.Errorf("mail.SendCollaboratorMail(fail to render): %v", err)
|
||||
}
|
||||
|
||||
msg := NewMailMessage([]string{u.Email}, subject, body)
|
||||
msg := NewMessage([]string{u.Email}, subject, body)
|
||||
msg.Info = fmt.Sprintf("UID: %d, send register mail", u.Id)
|
||||
|
||||
SendAsync(&msg)
|
||||
SendAsync(msg)
|
||||
return nil
|
||||
}
|
||||
+65
-119
@@ -7,16 +7,44 @@ package mailer
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/mail"
|
||||
"net/smtp"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gopkg.in/gomail.v2"
|
||||
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Info string // Message information for log purpose.
|
||||
*gomail.Message
|
||||
}
|
||||
|
||||
// NewMessageFrom creates new mail message object with custom From header.
|
||||
func NewMessageFrom(to []string, from, subject, body string) *Message {
|
||||
msg := gomail.NewMessage()
|
||||
msg.SetHeader("From", from)
|
||||
msg.SetHeader("To", to...)
|
||||
msg.SetHeader("Subject", subject)
|
||||
msg.SetDateHeader("Date", time.Now())
|
||||
msg.SetBody("text/plain", body)
|
||||
msg.AddAlternative("text/html", body)
|
||||
|
||||
return &Message{
|
||||
Message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// NewMessage creates new mail message object with default From header.
|
||||
func NewMessage(to []string, subject, body string) *Message {
|
||||
return NewMessageFrom(to, setting.MailService.From, subject, body)
|
||||
}
|
||||
|
||||
type loginAuth struct {
|
||||
username, password string
|
||||
}
|
||||
@@ -44,74 +72,24 @@ func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
To []string
|
||||
From string
|
||||
Subject string
|
||||
ReplyTo string
|
||||
Body string
|
||||
Type string
|
||||
Massive bool
|
||||
Info string
|
||||
type Sender struct {
|
||||
}
|
||||
|
||||
// create mail content
|
||||
func (m Message) Content() string {
|
||||
// set mail type
|
||||
contentType := "text/plain; charset=UTF-8"
|
||||
if m.Type == "html" {
|
||||
contentType = "text/html; charset=UTF-8"
|
||||
}
|
||||
func (s *Sender) Send(from string, to []string, msg io.WriterTo) error {
|
||||
opts := setting.MailService
|
||||
|
||||
// create mail content
|
||||
content := "From: " + m.From + "\r\nReply-To: " + m.ReplyTo + "\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body
|
||||
return content
|
||||
}
|
||||
|
||||
var mailQueue chan *Message
|
||||
|
||||
func NewContext() {
|
||||
if setting.MailService == nil {
|
||||
return
|
||||
}
|
||||
|
||||
mailQueue = make(chan *Message, setting.MailService.QueueLength)
|
||||
go processMailQueue()
|
||||
}
|
||||
|
||||
func processMailQueue() {
|
||||
for {
|
||||
select {
|
||||
case msg := <-mailQueue:
|
||||
num, err := Send(msg)
|
||||
tos := strings.Join(msg.To, ", ")
|
||||
info := ""
|
||||
if err != nil {
|
||||
if len(msg.Info) > 0 {
|
||||
info = ", info: " + msg.Info
|
||||
}
|
||||
log.Error(4, fmt.Sprintf("Async sent email %d succeed, not send emails: %s%s err: %s", num, tos, info, err))
|
||||
} else {
|
||||
log.Trace(fmt.Sprintf("Async sent email %d succeed, sent emails: %s%s", num, tos, info))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sendMail allows mail with self-signed certificates.
|
||||
func sendMail(settings *setting.Mailer, recipients []string, msgContent []byte) error {
|
||||
host, port, err := net.SplitHostPort(settings.Host)
|
||||
host, port, err := net.SplitHostPort(opts.Host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tlsconfig := &tls.Config{
|
||||
InsecureSkipVerify: settings.SkipVerify,
|
||||
InsecureSkipVerify: opts.SkipVerify,
|
||||
ServerName: host,
|
||||
}
|
||||
|
||||
if settings.UseCertificate {
|
||||
cert, err := tls.LoadX509KeyPair(settings.CertFile, settings.KeyFile)
|
||||
if opts.UseCertificate {
|
||||
cert, err := tls.LoadX509KeyPair(opts.CertFile, opts.KeyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -159,17 +137,16 @@ func sendMail(settings *setting.Mailer, recipients []string, msgContent []byte)
|
||||
}
|
||||
|
||||
canAuth, options := client.Extension("AUTH")
|
||||
|
||||
if canAuth && len(settings.User) > 0 {
|
||||
if canAuth && len(opts.User) > 0 {
|
||||
var auth smtp.Auth
|
||||
|
||||
if strings.Contains(options, "CRAM-MD5") {
|
||||
auth = smtp.CRAMMD5Auth(settings.User, settings.Passwd)
|
||||
auth = smtp.CRAMMD5Auth(opts.User, opts.Passwd)
|
||||
} else if strings.Contains(options, "PLAIN") {
|
||||
auth = smtp.PlainAuth("", settings.User, settings.Passwd, host)
|
||||
auth = smtp.PlainAuth("", opts.User, opts.Passwd, host)
|
||||
} else if strings.Contains(options, "LOGIN") {
|
||||
// Patch for AUTH LOGIN
|
||||
auth = LoginAuth(settings.User, settings.Passwd)
|
||||
auth = LoginAuth(opts.User, opts.Passwd)
|
||||
}
|
||||
|
||||
if auth != nil {
|
||||
@@ -179,15 +156,11 @@ func sendMail(settings *setting.Mailer, recipients []string, msgContent []byte)
|
||||
}
|
||||
}
|
||||
|
||||
if fromAddress, err := mail.ParseAddress(settings.From); err != nil {
|
||||
if err = client.Mail(from); err != nil {
|
||||
return err
|
||||
} else {
|
||||
if err = client.Mail(fromAddress.Address); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, rec := range recipients {
|
||||
for _, rec := range to {
|
||||
if err = client.Rcpt(rec); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -196,71 +169,44 @@ func sendMail(settings *setting.Mailer, recipients []string, msgContent []byte)
|
||||
w, err := client.Data()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = w.Write([]byte(msgContent)); err != nil {
|
||||
} else if _, err = msg.WriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = w.Close(); err != nil {
|
||||
} else if err = w.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return client.Quit()
|
||||
}
|
||||
|
||||
// Direct Send mail message
|
||||
func Send(msg *Message) (int, error) {
|
||||
log.Trace("Sending mails to: %s", strings.Join(msg.To, ", "))
|
||||
func processMailQueue() {
|
||||
sender := &Sender{}
|
||||
|
||||
// get message body
|
||||
content := msg.Content()
|
||||
|
||||
if len(msg.To) == 0 {
|
||||
return 0, fmt.Errorf("empty receive emails")
|
||||
} else if len(msg.Body) == 0 {
|
||||
return 0, fmt.Errorf("empty email body")
|
||||
}
|
||||
|
||||
if msg.Massive {
|
||||
// send mail to multiple emails one by one
|
||||
num := 0
|
||||
for _, to := range msg.To {
|
||||
body := []byte("To: " + to + "\r\n" + content)
|
||||
err := sendMail(setting.MailService, []string{to}, body)
|
||||
if err != nil {
|
||||
return num, err
|
||||
for {
|
||||
select {
|
||||
case msg := <-mailQueue:
|
||||
log.Trace("New e-mail sending request %s: %s", msg.GetHeader("To"), msg.Info)
|
||||
if err := gomail.Send(sender, msg.Message); err != nil {
|
||||
log.Error(4, "Fail to send e-mails %s: %s - %v", msg.GetHeader("To"), msg.Info, err)
|
||||
} else {
|
||||
log.Trace("E-mails sent %s: %s", msg.GetHeader("To"), msg.Info)
|
||||
}
|
||||
num++
|
||||
}
|
||||
return num, nil
|
||||
} else {
|
||||
body := []byte("To: " + strings.Join(msg.To, ",") + "\r\n" + content)
|
||||
|
||||
// send to multiple emails in one message
|
||||
err := sendMail(setting.MailService, msg.To, body)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return 1, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Async Send mail message
|
||||
var mailQueue chan *Message
|
||||
|
||||
func NewContext() {
|
||||
if setting.MailService == nil {
|
||||
return
|
||||
}
|
||||
|
||||
mailQueue = make(chan *Message, setting.MailService.QueueLength)
|
||||
go processMailQueue()
|
||||
}
|
||||
|
||||
func SendAsync(msg *Message) {
|
||||
go func() {
|
||||
mailQueue <- msg
|
||||
}()
|
||||
}
|
||||
|
||||
// Create html mail message
|
||||
func NewHtmlMessage(To []string, From, Subject, Body string) Message {
|
||||
return Message{
|
||||
To: To,
|
||||
From: setting.MailService.From,
|
||||
ReplyTo: From,
|
||||
Subject: Subject,
|
||||
Body: Body,
|
||||
Type: "html",
|
||||
}
|
||||
}
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
@font-face{font-family:octicons;src:url(../fonts/octicons.eot?#iefix&v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d) format('embedded-opentype'),url(../fonts/octicons.woff?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d) format('woff'),url(../fonts/octicons.ttf?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d) format('truetype'),url(../fonts/octicons.svg?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d#octicons) format('svg');font-weight:400;font-style:normal}.mega-octicon,.octicon{font:normal normal normal 16px/1 octicons;display:inline-block;text-decoration:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mega-octicon{font-size:32px}.octicon-alert:before{content:'\f02d'}.octicon-arrow-down:before{content:'\f03f'}.octicon-arrow-left:before{content:'\f040'}.octicon-arrow-right:before{content:'\f03e'}.octicon-arrow-small-down:before{content:'\f0a0'}.octicon-arrow-small-left:before{content:'\f0a1'}.octicon-arrow-small-right:before{content:'\f071'}.octicon-arrow-small-up:before{content:'\f09f'}.octicon-arrow-up:before{content:'\f03d'}.octicon-beaker:before,.octicon-microscope:before{content:'\f0dd'}.octicon-bell:before{content:'\f0de'}.octicon-book:before{content:'\f007'}.octicon-bookmark:before{content:'\f07b'}.octicon-briefcase:before{content:'\f0d3'}.octicon-broadcast:before{content:'\f048'}.octicon-browser:before{content:'\f0c5'}.octicon-bug:before{content:'\f091'}.octicon-calendar:before{content:'\f068'}.octicon-check:before{content:'\f03a'}.octicon-checklist:before{content:'\f076'}.octicon-chevron-down:before{content:'\f0a3'}.octicon-chevron-left:before{content:'\f0a4'}.octicon-chevron-right:before{content:'\f078'}.octicon-chevron-up:before{content:'\f0a2'}.octicon-circle-slash:before{content:'\f084'}.octicon-circuit-board:before{content:'\f0d6'}.octicon-clippy:before{content:'\f035'}.octicon-clock:before{content:'\f046'}.octicon-cloud-download:before{content:'\f00b'}.octicon-cloud-upload:before{content:'\f00c'}.octicon-code:before{content:'\f05f'}.octicon-color-mode:before{content:'\f065'}.octicon-comment-add:before,.octicon-comment:before{content:'\f02b'}.octicon-comment-discussion:before{content:'\f04f'}.octicon-credit-card:before{content:'\f045'}.octicon-dash:before{content:'\f0ca'}.octicon-dashboard:before{content:'\f07d'}.octicon-database:before{content:'\f096'}.octicon-clone:before,.octicon-desktop-download:before{content:'\f0dc'}.octicon-device-camera:before{content:'\f056'}.octicon-device-camera-video:before{content:'\f057'}.octicon-device-desktop:before{content:'\f27c'}.octicon-device-mobile:before{content:'\f038'}.octicon-diff:before{content:'\f04d'}.octicon-diff-added:before{content:'\f06b'}.octicon-diff-ignored:before{content:'\f099'}.octicon-diff-modified:before{content:'\f06d'}.octicon-diff-removed:before{content:'\f06c'}.octicon-diff-renamed:before{content:'\f06e'}.octicon-ellipsis:before{content:'\f09a'}.octicon-eye-unwatch:before,.octicon-eye-watch:before,.octicon-eye:before{content:'\f04e'}.octicon-file-binary:before{content:'\f094'}.octicon-file-code:before{content:'\f010'}.octicon-file-directory:before{content:'\f016'}.octicon-file-media:before{content:'\f012'}.octicon-file-pdf:before{content:'\f014'}.octicon-file-submodule:before{content:'\f017'}.octicon-file-symlink-directory:before{content:'\f0b1'}.octicon-file-symlink-file:before{content:'\f0b0'}.octicon-file-text:before{content:'\f011'}.octicon-file-zip:before{content:'\f013'}.octicon-flame:before{content:'\f0d2'}.octicon-fold:before{content:'\f0cc'}.octicon-gear:before{content:'\f02f'}.octicon-gift:before{content:'\f042'}.octicon-gist:before{content:'\f00e'}.octicon-gist-secret:before{content:'\f08c'}.octicon-git-branch-create:before,.octicon-git-branch-delete:before,.octicon-git-branch:before{content:'\f020'}.octicon-git-commit:before{content:'\f01f'}.octicon-git-compare:before{content:'\f0ac'}.octicon-git-merge:before{content:'\f023'}.octicon-git-pull-request-abandoned:before,.octicon-git-pull-request:before{content:'\f009'}.octicon-globe:before{content:'\f0b6'}.octicon-graph:before{content:'\f043'}.octicon-heart:before{content:'\2665'}.octicon-history:before{content:'\f07e'}.octicon-home:before{content:'\f08d'}.octicon-horizontal-rule:before{content:'\f070'}.octicon-hubot:before{content:'\f09d'}.octicon-inbox:before{content:'\f0cf'}.octicon-info:before{content:'\f059'}.octicon-issue-closed:before{content:'\f028'}.octicon-issue-opened:before{content:'\f026'}.octicon-issue-reopened:before{content:'\f027'}.octicon-jersey:before{content:'\f019'}.octicon-key:before{content:'\f049'}.octicon-keyboard:before{content:'\f00d'}.octicon-law:before{content:'\f0d8'}.octicon-light-bulb:before{content:'\f000'}.octicon-link:before{content:'\f05c'}.octicon-link-external:before{content:'\f07f'}.octicon-list-ordered:before{content:'\f062'}.octicon-list-unordered:before{content:'\f061'}.octicon-location:before{content:'\f060'}.octicon-gLine truncated
|
||||
@font-face{font-family:octicons;src:url(../fonts/octicons.eot?#iefix&v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d) format('embedded-opentype'),url(../fonts/octicons.woff?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d) format('woff'),url(../fonts/octicons.ttf?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d) format('truetype'),url(../fonts/octicons.svg?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d#octicons) format('svg');font-weight:400;font-style:normal}.mega-octicon,.octicon{font:normal normal normal 16px/1 octicons;display:inline-block;text-decoration:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mega-octicon{font-size:32px}.octicon-alert:before{content:'\f02d'}.octicon-arrow-down:before{content:'\f03f'}.octicon-arrow-left:before{content:'\f040'}.octicon-arrow-right:before{content:'\f03e'}.octicon-arrow-small-down:before{content:'\f0a0'}.octicon-arrow-small-left:before{content:'\f0a1'}.octicon-arrow-small-right:before{content:'\f071'}.octicon-arrow-small-up:before{content:'\f09f'}.octicon-arrow-up:before{content:'\f03d'}.octicon-beaker:before,.octicon-microscope:before{content:'\f0dd'}.octicon-bell:before{content:'\f0de'}.octicon-book:before{content:'\f007'}.octicon-bookmark:before{content:'\f07b'}.octicon-briefcase:before{content:'\f0d3'}.octicon-broadcast:before{content:'\f048'}.octicon-browser:before{content:'\f0c5'}.octicon-bug:before{content:'\f091'}.octicon-calendar:before{content:'\f068'}.octicon-check:before{content:'\f03a'}.octicon-checklist:before{content:'\f076'}.octicon-chevron-down:before{content:'\f0a3'}.octicon-chevron-left:before{content:'\f0a4'}.octicon-chevron-right:before{content:'\f078'}.octicon-chevron-up:before{content:'\f0a2'}.octicon-circle-slash:before{content:'\f084'}.octicon-circuit-board:before{content:'\f0d6'}.octicon-clippy:before{content:'\f035'}.octicon-clock:before{content:'\f046'}.octicon-cloud-download:before{content:'\f00b'}.octicon-cloud-upload:before{content:'\f00c'}.octicon-code:before{content:'\f05f'}.octicon-color-mode:before{content:'\f065'}.octicon-comment-add:before,.octicon-comment:before{content:'\f02b'}.octicon-comment-discussion:before{content:'\f04f'}.octicon-credit-card:before{content:'\f045'}.octicon-dash:before{content:'\f0ca'}.octicon-dashboard:before{content:'\f07d'}.octicon-database:before{content:'\f096'}.octicon-clone:before,.octicon-desktop-download:before{content:'\f0dc'}.octicon-device-camera:before{content:'\f056'}.octicon-device-camera-video:before{content:'\f057'}.octicon-device-desktop:before{content:'\f27c'}.octicon-device-mobile:before{content:'\f038'}.octicon-diff:before{content:'\f04d'}.octicon-diff-added:before{content:'\f06b'}.octicon-diff-ignored:before{content:'\f099'}.octicon-diff-modified:before{content:'\f06d'}.octicon-diff-removed:before{content:'\f06c'}.octicon-diff-renamed:before{content:'\f06e'}.octicon-ellipsis:before{content:'\f09a'}.octicon-eye-unwatch:before,.octicon-eye-watch:before,.octicon-eye:before{content:'\f04e'}.octicon-file-binary:before{content:'\f094'}.octicon-file-code:before{content:'\f010'}.octicon-file-directory:before{content:'\f016'}.octicon-file-media:before{content:'\f012'}.octicon-file-pdf:before{content:'\f014'}.octicon-file-submodule:before{content:'\f017'}.octicon-file-symlink-directory:before{content:'\f0b1'}.octicon-file-symlink-file:before{content:'\f0b0'}.octicon-file-text:before{content:'\f011'}.octicon-file-zip:before{content:'\f013'}.octicon-flame:before{content:'\f0d2'}.octicon-fold:before{content:'\f0cc'}.octicon-gear:before{content:'\f02f'}.octicon-gift:before{content:'\f042'}.octicon-gist:before{content:'\f00e'}.octicon-gist-secret:before{content:'\f08c'}.octicon-git-branch-create:before,.octicon-git-branch-delete:before,.octicon-git-branch:before{content:'\f020'}.octicon-git-commit:before{content:'\f01f'}.octicon-git-compare:before{content:'\f0ac'}.octicon-git-merge:before{content:'\f023'}.octicon-git-pull-request-abandoned:before,.octicon-git-pull-request:before{content:'\f009'}.octicon-globe:before{content:'\f0b6'}.octicon-graph:before{content:'\f043'}.octicon-heart:before{content:'\2665'}.octicon-history:before{content:'\f07e'}.octicon-home:before{content:'\f08d'}.octicon-horizontal-rule:before{content:'\f070'}.octicon-hubot:before{content:'\f09d'}.octicon-inbox:before{content:'\f0cf'}.octicon-info:before{content:'\f059'}.octicon-issue-closed:before{content:'\f028'}.octicon-issue-opened:before{content:'\f026'}.octicon-issue-reopened:before{content:'\f027'}.octicon-jersey:before{content:'\f019'}.octicon-key:before{content:'\f049'}.octicon-keyboard:before{content:'\f00d'}.octicon-law:before{content:'\f0d8'}.octicon-light-bulb:before{content:'\f000'}.octicon-link:before{content:'\f05c'}.octicon-link-external:before{content:'\f07f'}.octicon-list-ordered:before{content:'\f062'}.octicon-list-unordered:before{content:'\f061'}.octicon-location:before{content:'\f060'}.octicon-gLine truncated
|
||||
@@ -46,6 +46,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.user.activate,
|
||||
.signin,
|
||||
.signup {
|
||||
@input-padding: 200px!important;
|
||||
|
||||
@@ -20,5 +20,6 @@ func TemplatePreview(ctx *middleware.Context) {
|
||||
ctx.Data["ActiveCodeLives"] = setting.Service.ActiveCodeLives / 60
|
||||
ctx.Data["ResetPwdCodeLives"] = setting.Service.ResetPwdCodeLives / 60
|
||||
ctx.Data["CurDbValue"] = ""
|
||||
|
||||
ctx.HTML(200, base.TplName(ctx.Params("*")))
|
||||
}
|
||||
+1
-1
@@ -45,6 +45,7 @@ func checkRunMode() {
|
||||
|
||||
func NewServices() {
|
||||
setting.NewServices()
|
||||
mailer.NewContext()
|
||||
social.NewOauthService()
|
||||
}
|
||||
|
||||
@@ -53,7 +54,6 @@ func GlobalInit() {
|
||||
setting.NewContext()
|
||||
log.Trace("Custom path: %s", setting.CustomPath)
|
||||
log.Trace("Log path: %s", setting.LogRootPath)
|
||||
mailer.NewContext()
|
||||
models.LoadConfigs()
|
||||
NewServices()
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ func SignUpPost(ctx *middleware.Context, cpt *captcha.Captcha, form auth.Registe
|
||||
|
||||
// Send confirmation e-mail, no need for social account.
|
||||
if !isOauth && setting.Service.RegisterEmailConfirm && u.Id > 1 {
|
||||
mailer.SendRegisterMail(ctx.Render, u)
|
||||
mailer.SendActivateAccountMail(ctx.Context, u)
|
||||
ctx.Data["IsSendRegisterMail"] = true
|
||||
ctx.Data["Email"] = u.Email
|
||||
ctx.Data["Hours"] = setting.Service.ActiveCodeLives / 60
|
||||
@@ -278,7 +278,7 @@ func Activate(ctx *middleware.Context) {
|
||||
ctx.Data["ResendLimited"] = true
|
||||
} else {
|
||||
ctx.Data["Hours"] = setting.Service.ActiveCodeLives / 60
|
||||
mailer.SendActiveMail(ctx.Render, ctx.User)
|
||||
mailer.SendActivateAccountMail(ctx.Context, ctx.User)
|
||||
|
||||
if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
|
||||
log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
|
||||
|
||||
@@ -225,7 +225,7 @@ func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) {
|
||||
|
||||
// Send confirmation e-mail
|
||||
if setting.Service.RegisterEmailConfirm {
|
||||
mailer.SendActivateEmail(ctx.Render, ctx.User, e)
|
||||
mailer.SendActivateEmailMail(ctx.Context, ctx.User, e)
|
||||
|
||||
if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
|
||||
log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{.User.Name}}, please activate your account</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>Hi <b>{{.User.Name}}</b>, thanks for registering at {{.AppName}}!</p>
|
||||
<p>Please click the following link to verify your e-mail address within <b>{{.ActiveCodeLives}} hours</b>:</p>
|
||||
<p><a href="{{.AppUrl}}user/activate?code={{.Code}}">{{.AppUrl}}user/activate?code={{.Code}}</a></p>
|
||||
<p>Not working? Try copying and pasting it to your browser.</p>
|
||||
<p>© 2015 <a target="_blank" href="http://gogs.io">Gogs: Go Git Service</a></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,33 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{.User.Name}}, please activate your account</title>
|
||||
</head>
|
||||
<body style="background:#eee;">
|
||||
<div style="color:#333; font:12px/1.5 Tahoma,Arial,sans-serif;; text-shadow:1px 1px #fff; padding:0; margin:0;">
|
||||
<div style="width:600px;margin:0 auto; padding:40px 0 20px;">
|
||||
<div style="border:1px solid #d9d9d9;border-radius:3px; background:#fff; box-shadow: 0px 2px 5px rgba(0, 0, 0,.05); -webkit-box-shadow: 0px 2px 5px rgba(0, 0, 0,.05);">
|
||||
<div style="padding: 20px 15px;">
|
||||
<h1 style="font-size:20px; padding:10px 0 20px; margin:0; border-bottom:1px solid #ddd;"><img src="{{.AppUrl}}/img/favicon.png" style="height: 32px; margin-bottom: -10px;"> <a style="color:#333;text-decoration:none;" target="_blank" href="{{.AppUrl}}">{{.AppName}}</a></h1>
|
||||
<div style="padding:40px 15px;">
|
||||
<div style="font-size:16px; padding-bottom:30px; font-weight:bold;">
|
||||
Hi <span style="color: #00BFFF;">{{.User.Name}}</span>,
|
||||
</div>
|
||||
<div style="font-size:14px; padding:0 15px;">
|
||||
<p style="margin:0;padding:0 0 9px 0;">Please click the following link to verify your e-mail address within <b>{{.ActiveCodeLives}} hours</b>.</p>
|
||||
<p style="margin:0;padding:0 0 9px 0;">
|
||||
<a href="{{.AppUrl}}user/activate?code={{.Code}}">{{.AppUrl}}user/activate?code={{.Code}}</a>
|
||||
</p>
|
||||
<p style="margin:0;padding:0 0 9px 0;">Not working? Try copying and pasting it to your browser.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="color:#aaa;padding:10px;text-align:center;">
|
||||
© 2014 <a style="color:#888;text-decoration:none;" target="_blank" href="http://gogits.org">Gogs: Go Git Service</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,33 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{.User.Name}}, welcome to {{.AppName}}</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{.User.Name}}, welcome to {{.AppName}}</title>
|
||||
</head>
|
||||
<body style="background:#eee;">
|
||||
<div style="color:#333; font:12px/1.5 Tahoma,Arial,sans-serif;; text-shadow:1px 1px #fff; padding:0; margin:0;">
|
||||
<div style="width:600px;margin:0 auto; padding:40px 0 20px;">
|
||||
<div style="border:1px solid #d9d9d9;border-radius:3px; background:#fff; box-shadow: 0px 2px 5px rgba(0, 0, 0,.05); -webkit-box-shadow: 0px 2px 5px rgba(0, 0, 0,.05);">
|
||||
<div style="padding: 20px 15px;">
|
||||
<h1 style="font-size:20px; padding:10px 0 20px; margin:0; border-bottom:1px solid #ddd;"><img src="{{.AppUrl}}/img/favicon.png" style="height: 32px; margin-bottom: -10px;"> <a style="color:#333;text-decoration:none;" target="_blank" href="{{.AppUrl}}">{{.AppName}}</a></h1>
|
||||
<div style="padding:40px 15px;">
|
||||
<div style="font-size:16px; padding-bottom:30px; font-weight:bold;">
|
||||
Hi <span style="color: #00BFFF;">{{.User.Name}}</span>, this is your registration email for {{.AppName}}!
|
||||
</div>
|
||||
<div style="font-size:14px; padding:0 15px;">
|
||||
<p style="margin:0;padding:0 0 9px 0;">Please click the following link to verify your e-mail address within <b>{{.ActiveCodeLives}} hours</b>.</p>
|
||||
<p style="margin:0;padding:0 0 9px 0;">
|
||||
<a href="{{.AppUrl}}user/activate?code={{.Code}}">{{.AppUrl}}user/activate?code={{.Code}}</a>
|
||||
</p>
|
||||
<p style="margin:0;padding:0 0 9px 0;">Not working? Try copying and pasting it to your browser.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="color:#aaa;padding:10px;text-align:center;">
|
||||
© 2014 <a style="color:#888;text-decoration:none;" target="_blank" href="http://gogits.org">Gogs: Go Git Service</a>
|
||||
</div>
|
||||
|
||||
<body class="mail register success">
|
||||
<div class="ui segment">
|
||||
<div class="ui header">
|
||||
<img class="ui image" src="{{.AppUrl}}/img/favicon.png">
|
||||
{{.AppName}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<p>Hi <b>{{.User.Name}}</b>, this is your registration email for {{.AppName}}!</p>
|
||||
<p>Please click the following link to verify your e-mail address within <b>{{.ActiveCodeLives}} hours</b>:</p>
|
||||
<p><a href="{{.AppUrl}}user/activate?code={{.Code}}">{{.AppUrl}}user/activate?code={{.Code}}</a></p>
|
||||
<p>Not working? Try copying and pasting it to your browser.</p>
|
||||
</div>
|
||||
<p class="copyright text grey">© 2015 <a target="_blank" href="http://gogs.io">Gogs: Go Git Service</a></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,39 +1,45 @@
|
||||
{{template "ng/base/head" .}}
|
||||
{{template "ng/base/header" .}}
|
||||
<div id="sign-wrapper">
|
||||
<form class="form-align form panel sign-panel sign-form container panel-radius" id="sign-up-form" action="{{AppSubUrl}}/user/activate" method="post">
|
||||
{{template "base/head" .}}
|
||||
<div class="user activate">
|
||||
<div class="ui middle very relaxed page grid">
|
||||
<div class="column">
|
||||
<form class="ui form" action="{{AppSubUrl}}/user/activate" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="panel-header">
|
||||
<h2>{{.i18n.Tr "auth.active_your_account"}}</h2>
|
||||
</div>
|
||||
<div class="panel-content">
|
||||
{{if .IsActivatePage}}
|
||||
<h2 class="ui top attached header">
|
||||
{{.i18n.Tr "auth.active_your_account"}}
|
||||
</h2>
|
||||
<div class="ui attached segment">
|
||||
{{if .IsActivatePage}}
|
||||
{{if .ServiceNotEnabled}}
|
||||
<p>{{.i18n.Tr "auth.disable_register_mail"}}</p>
|
||||
{{else if .ResendLimited}}
|
||||
<p>{{.i18n.Tr "auth.resent_limit_prompt"}}</p>
|
||||
{{else}}
|
||||
<p>{{.i18n.Tr "auth.confirmation_mail_sent_prompt" .SignedUser.Email .Hours | Str2html}}</p>
|
||||
<hr/>
|
||||
<label></label>
|
||||
<a class="btn btn-green btn-large btn-link btn-radius" href="http://{{Mail2Domain .SignedUser.Email}}">{{.i18n.Tr "auth.sign_in_email"}}</a>
|
||||
<div class="ui divider"></div>
|
||||
<div class="text right">
|
||||
<a class="ui green button" href="http://{{Mail2Domain .SignedUser.Email}}">{{.i18n.Tr "auth.sign_in_to_account"}}</a>
|
||||
</div>
|
||||
{{end}}
|
||||
{{else}}
|
||||
{{else}}
|
||||
{{if .IsSendRegisterMail}}
|
||||
<p>{{.i18n.Tr "auth.confirmation_mail_sent_prompt" .Email .Hours | Str2html}}</p>
|
||||
<hr/>
|
||||
<label></label>
|
||||
<a class="btn btn-green btn-large btn-link btn-radius" href="http://{{Mail2Domain .Email}}">{{.i18n.Tr "auth.sign_in_to_account"}}</a>
|
||||
<div class="ui divider"></div>
|
||||
<div class="text right">
|
||||
<a class="ui green button" href="http://{{Mail2Domain .Email}}">{{.i18n.Tr "auth.sign_in_to_account"}}</a>
|
||||
</div>
|
||||
{{else if .IsActivateFailed}}
|
||||
<p>{{.i18n.Tr "auth.invalid_code"}}</p>
|
||||
{{else}}
|
||||
<p>{{.i18n.Tr "auth.has_unconfirmed_mail" .SignedUser.Name .SignedUser.Email | Str2html}}</p>
|
||||
<hr/>
|
||||
<label></label>
|
||||
<button class="btn btn-blue btn-large btn-radius">{{.i18n.Tr "auth.resend_mail"}}</button>
|
||||
<div class="ui divider"></div>
|
||||
<div class="text right">
|
||||
<button class="ui blue button" href="http://{{Mail2Domain .SignedUser.Email}}">{{.i18n.Tr "auth.resend_mail"}}</button>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "ng/base/footer" .}}
|
||||
{{template "base/footer" .}}
|
||||
Reference in new issue
Block a user