mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-28 12:16:17 +01:00
new delete account UI and password confirmation
This commit is contained in:
parent
81b8427438
commit
2493454587
14 changed files with 137 additions and 52 deletions
10
cmd/web.go
10
cmd/web.go
|
@ -249,7 +249,7 @@ func runWeb(ctx *cli.Context) {
|
|||
})
|
||||
}, ignSignIn)
|
||||
|
||||
// User.
|
||||
// ***** START: User *****
|
||||
m.Group("/user", func() {
|
||||
m.Get("/login", user.SignIn)
|
||||
m.Post("/login", bindIgnErr(auth.SignInForm{}), user.SignInPost)
|
||||
|
@ -259,6 +259,7 @@ func runWeb(ctx *cli.Context) {
|
|||
m.Get("/reset_password", user.ResetPasswd)
|
||||
m.Post("/reset_password", user.ResetPasswdPost)
|
||||
}, reqSignOut)
|
||||
|
||||
m.Group("/user/settings", func() {
|
||||
m.Get("", user.Settings)
|
||||
m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
|
||||
|
@ -272,7 +273,11 @@ func runWeb(ctx *cli.Context) {
|
|||
m.Get("/social", user.SettingsSocial)
|
||||
m.Combo("/applications").Get(user.SettingsApplications).Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost)
|
||||
m.Route("/delete", "GET,POST", user.SettingsDelete)
|
||||
}, reqSignIn)
|
||||
}, reqSignIn, func(ctx *middleware.Context) {
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["HasOAuthService"] = setting.OauthService != nil
|
||||
})
|
||||
|
||||
m.Group("/user", func() {
|
||||
// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds)
|
||||
m.Any("/activate", user.Activate)
|
||||
|
@ -282,6 +287,7 @@ func runWeb(ctx *cli.Context) {
|
|||
m.Post("/forget_password", user.ForgotPasswdPost)
|
||||
m.Get("/logout", user.SignOut)
|
||||
})
|
||||
// ***** END: User *****
|
||||
|
||||
// Gravatar service.
|
||||
avt := avatar.CacheServer("public/img/avatar/", "public/img/avatar_default.jpg")
|
||||
|
|
|
@ -395,6 +395,26 @@
|
|||
"strictMath": 0,
|
||||
"strictUnits": 0
|
||||
},
|
||||
"\/public\/less\/_user.less": {
|
||||
"allowInsecureImports": 0,
|
||||
"createSourceMap": 0,
|
||||
"disableJavascript": 0,
|
||||
"fileType": 1,
|
||||
"ieCompatibility": 1,
|
||||
"ignore": 1,
|
||||
"ignoreWasSetByUser": 0,
|
||||
"inputAbbreviatedPath": "\/public\/less\/_user.less",
|
||||
"outputAbbreviatedPath": "\/public\/css\/_user.css",
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0,
|
||||
"outputStyle": 0,
|
||||
"relativeURLS": 0,
|
||||
"shouldRunAutoprefixer": 0,
|
||||
"shouldRunBless": 0,
|
||||
"strictImports": 0,
|
||||
"strictMath": 0,
|
||||
"strictUnits": 0
|
||||
},
|
||||
"\/public\/less\/gogs.less": {
|
||||
"allowInsecureImports": 0,
|
||||
"createSourceMap": 0,
|
||||
|
|
2
gogs.go
2
gogs.go
|
@ -17,7 +17,7 @@ import (
|
|||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const APP_VER = "0.6.5.0818 Beta"
|
||||
const APP_VER = "0.6.5.0819 Beta"
|
||||
|
||||
func init() {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
|
2
public/css/gogs.min.css
vendored
2
public/css/gogs.min.css
vendored
File diff suppressed because one or more lines are too long
|
@ -336,6 +336,11 @@ $(document).ready(function () {
|
|||
$('.delete.modal').modal({
|
||||
closable: false,
|
||||
onApprove: function () {
|
||||
if ($this.data('type') == "form") {
|
||||
$($this.data('form')).submit();
|
||||
return;
|
||||
}
|
||||
|
||||
$.post($this.data('url'), {
|
||||
"_csrf": csrf,
|
||||
"id": $this.data("id")
|
||||
|
|
|
@ -102,6 +102,15 @@ img {
|
|||
padding-left: 0.75rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.warning {
|
||||
&.header {
|
||||
background-color: #F9EDBE!important;
|
||||
border-color: #F0C36D;
|
||||
}
|
||||
&.segment {
|
||||
border-color: #F0C36D;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar.image {
|
||||
border-radius: 3px;
|
||||
|
|
4
public/less/_user.less
Normal file
4
public/less/_user.less
Normal file
|
@ -0,0 +1,4 @@
|
|||
.user {
|
||||
padding-top: 15px;
|
||||
padding-bottom: @footer-margin * 3;
|
||||
}
|
|
@ -5,4 +5,5 @@
|
|||
@import "_install";
|
||||
@import "_form";
|
||||
@import "_repository";
|
||||
@import "_user";
|
||||
@import "_admin";
|
|
@ -33,14 +33,12 @@ const (
|
|||
|
||||
func Settings(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["PageIsSettingsProfile"] = true
|
||||
ctx.HTML(200, SETTINGS_PROFILE)
|
||||
}
|
||||
|
||||
func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["PageIsSettingsProfile"] = true
|
||||
|
||||
if ctx.HasError() {
|
||||
|
@ -132,7 +130,6 @@ func SettingsAvatar(ctx *middleware.Context, form auth.UploadAvatarForm) {
|
|||
|
||||
func SettingsEmails(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["PageIsSettingsEmails"] = true
|
||||
|
||||
emails, err := models.GetEmailAddresses(ctx.User.Id)
|
||||
|
@ -147,7 +144,6 @@ func SettingsEmails(ctx *middleware.Context) {
|
|||
|
||||
func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["PageIsSettingsEmails"] = true
|
||||
|
||||
emails, err := models.GetEmailAddresses(ctx.User.Id)
|
||||
|
@ -232,14 +228,12 @@ func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) {
|
|||
|
||||
func SettingsPassword(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["PageIsSettingsPassword"] = true
|
||||
ctx.HTML(200, SETTINGS_PASSWORD)
|
||||
}
|
||||
|
||||
func SettingsPasswordPost(ctx *middleware.Context, form auth.ChangePasswordForm) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["PageIsSettingsPassword"] = true
|
||||
|
||||
if ctx.HasError() {
|
||||
|
@ -273,7 +267,6 @@ func SettingsPasswordPost(ctx *middleware.Context, form auth.ChangePasswordForm)
|
|||
|
||||
func SettingsSSHKeys(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["PageIsSettingsSSHKeys"] = true
|
||||
|
||||
var err error
|
||||
|
@ -288,7 +281,6 @@ func SettingsSSHKeys(ctx *middleware.Context) {
|
|||
|
||||
func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["PageIsSettingsSSHKeys"] = true
|
||||
|
||||
var err error
|
||||
|
@ -355,7 +347,6 @@ func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
|
|||
|
||||
func SettingsSocial(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["PageIsSettingsSocial"] = true
|
||||
|
||||
// Unbind social account.
|
||||
|
@ -381,7 +372,6 @@ func SettingsSocial(ctx *middleware.Context) {
|
|||
|
||||
func SettingsApplications(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["PageIsSettingsApplications"] = true
|
||||
|
||||
// Delete access token.
|
||||
|
@ -409,7 +399,6 @@ func SettingsApplications(ctx *middleware.Context) {
|
|||
// FIXME: split to two different functions and pages to handle access token and oauth2
|
||||
func SettingsApplicationsPost(ctx *middleware.Context, form auth.NewAccessTokenForm) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["PageIsSettingsApplications"] = true
|
||||
|
||||
switch ctx.Query("type") {
|
||||
|
@ -437,11 +426,18 @@ func SettingsApplicationsPost(ctx *middleware.Context, form auth.NewAccessTokenF
|
|||
|
||||
func SettingsDelete(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
ctx.Data["PageIsSettingsDelete"] = true
|
||||
|
||||
if ctx.Req.Method == "POST" {
|
||||
// FIXME: validate password.
|
||||
if _, err := models.UserSignIn(ctx.User.Name, ctx.Query("password")); err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), SETTINGS_DELETE, nil)
|
||||
} else {
|
||||
ctx.Handle(500, "UserSignIn", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DeleteUser(ctx.User); err != nil {
|
||||
switch {
|
||||
case models.IsErrUserOwnRepos(err):
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.6.5.0818 Beta
|
||||
0.6.5.0819 Beta
|
|
@ -110,7 +110,7 @@
|
|||
<i class="octicon icon octicon-person"></i>
|
||||
{{.i18n.Tr "your_profile"}}<!-- Your profile -->
|
||||
</a>
|
||||
<a class="item" href="{{AppSubUrl}}/user/settings">
|
||||
<a class="{{if .PageIsUserSettings}}active{{end}} item" href="{{AppSubUrl}}/user/settings">
|
||||
<i class="octicon icon octicon-settings"></i>
|
||||
{{.i18n.Tr "your_settings"}}<!-- Your settings -->
|
||||
</a>
|
||||
|
@ -121,7 +121,7 @@
|
|||
{{if .IsAdmin}}
|
||||
<div class="divider"></div>
|
||||
|
||||
<a class="item" href="{{AppSubUrl}}/admin">
|
||||
<a class="{{if .PageIsAdmin}}active{{end}} item" href="{{AppSubUrl}}/admin">
|
||||
<i class="icon settings"></i>
|
||||
{{.i18n.Tr "admin_panel"}}<!-- Admin Panel -->
|
||||
</a>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<label for="auth_username">{{.i18n.Tr "username"}}</label>
|
||||
<input id="auth_username" name="auth_username" value="{{.auth_username}}" {{if not .auth_username}}data-need-clear="true"{{end}}>
|
||||
</div>
|
||||
<input class="fake">
|
||||
<input class="fake" type="password">
|
||||
<div class="inline field {{if .Err_Auth}}error{{end}}">
|
||||
<label for="auth_password">{{.i18n.Tr "password"}}</label>
|
||||
<input id="auth_password" name="auth_password" type="password" value="{{.auth_password}}">
|
||||
|
|
|
@ -1,35 +1,51 @@
|
|||
{{template "ng/base/head" .}}
|
||||
{{template "ng/base/header" .}}
|
||||
<div id="setting-wrapper" class="main-wrapper">
|
||||
<div id="user-profile-setting" class="container clear">
|
||||
{{template "user/settings/nav" .}}
|
||||
<div class="grid-4-5 left">
|
||||
<div class="setting-content">
|
||||
{{template "ng/base/alert" .}}
|
||||
<div id="setting-content">
|
||||
<div id="user-profile-setting-content" class="panel panel-warning panel-radius">
|
||||
<p class="panel-header"><strong>{{.i18n.Tr "settings.delete_account"}}</strong></p>
|
||||
<div class="panel-body panel-content">
|
||||
<span class="alert alert-red alert-radius block"><i class="octicon octicon-alert"></i>{{.i18n.Tr "settings.delete_prompt" | Str2html}}</span>
|
||||
<form id="delete-account-form" action="{{AppSubUrl}}/user/settings/delete" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<p class="field">
|
||||
<span class="form-label"></span>
|
||||
<button class="btn btn-red btn-large btn-radius" id="delete-account-btn" href="#delete-account-modal">{{.i18n.Tr "settings.confirm_delete_account"}}</button>
|
||||
</p>
|
||||
</form>
|
||||
<div class="white-popup-block mfp-hide" id="delete-account-modal">
|
||||
<h1 class="text-red">{{.i18n.Tr "settings.delete_account_title"}}</h1>
|
||||
<p>{{.i18n.Tr "settings.delete_account_desc"}}</p>
|
||||
<br>
|
||||
<button class="btn btn-red btn-large btn-radius" id="delete-account-submit">{{.i18n.Tr "settings.continue"}}</button>
|
||||
<button class="btn btn-large btn-radius popup-modal-dismiss">{{.i18n.Tr "settings.cancel"}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/head" .}}
|
||||
<div class="user settings">
|
||||
<div class="ui container">
|
||||
<div class="ui grid">
|
||||
{{template "user/settings/navbar" .}}
|
||||
<div class="twelve wide column content">
|
||||
{{template "base/alert" .}}
|
||||
<h4 class="ui top attached warning header">
|
||||
{{.i18n.Tr "settings.delete_account"}}
|
||||
</h4>
|
||||
<div class="ui attached warning segment">
|
||||
<div class="ui red message">
|
||||
<p>{{.i18n.Tr "settings.delete_prompt" | Str2html}}</p>
|
||||
</div>
|
||||
<form class="ui form" id="delete-form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input class="fake" type="password">
|
||||
<div class="inline required field {{if .Err_Password}}error{{end}}">
|
||||
<label for="password">{{.i18n.Tr "password"}}</label>
|
||||
<input id="password" name="password" type="password" autofocus required>
|
||||
</div>
|
||||
<div class="ui red button delete-button" data-type="form" data-form="#delete-form">
|
||||
{{.i18n.Tr "settings.confirm_delete_account"}}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "ng/base/footer" .}}
|
||||
|
||||
<div class="ui small basic delete modal">
|
||||
<div class="ui icon header">
|
||||
<i class="trash icon"></i>
|
||||
{{.i18n.Tr "settings.delete_account_title"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.i18n.Tr "settings.delete_account_desc"}}</p>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="ui red basic inverted cancel button">
|
||||
<i class="remove icon"></i>
|
||||
{{.i18n.Tr "modal.no"}}
|
||||
</div>
|
||||
<div class="ui green basic inverted ok button">
|
||||
<i class="checkmark icon"></i>
|
||||
{{.i18n.Tr "modal.yes"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
28
templates/user/settings/navbar.tmpl
Normal file
28
templates/user/settings/navbar.tmpl
Normal file
|
@ -0,0 +1,28 @@
|
|||
<div class="four wide column">
|
||||
<div class="ui vertical menu">
|
||||
<div class="header item">{{.i18n.Tr "settings"}}</div>
|
||||
<a class="{{if .PageIsSettingsProfile}}active{{end}} item" href="{{AppSubUrl}}/user/settings">
|
||||
{{.i18n.Tr "settings.profile"}}
|
||||
</a>
|
||||
<a class="{{if .PageIsSettingsPassword}}active{{end}} item" href="{{AppSubUrl}}/user/settings/password">
|
||||
{{.i18n.Tr "settings.password"}}
|
||||
</a>
|
||||
<a class="{{if .PageIsSettingsEmails}}active{{end}} item" href="{{AppSubUrl}}/user/settings/email">
|
||||
{{.i18n.Tr "settings.emails"}}
|
||||
</a>
|
||||
<a class="{{if .PageIsSettingsSSHKeys}}active{{end}} item" href="{{AppSubUrl}}/user/settings/ssh">
|
||||
{{.i18n.Tr "settings.ssh_keys"}}
|
||||
</a>
|
||||
{{if .HasOAuthService}}
|
||||
<a class="{{if .PageIsSettingsSocial}}active{{end}} item" href="{{AppSubUrl}}/user/settings/social">
|
||||
{{.i18n.Tr "settings.social"}}
|
||||
</a>
|
||||
{{end}}
|
||||
<a class="{{if .PageIsSettingsApplications}}active{{end}} item" href="{{AppSubUrl}}/user/settings/applications">
|
||||
{{.i18n.Tr "settings.applications"}}
|
||||
</a>
|
||||
<a class="{{if .PageIsSettingsDelete}}active{{end}} item" href="{{AppSubUrl}}/user/settings/delete">
|
||||
{{.i18n.Tr "settings.delete"}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in a new issue