[chore] Warn about email/password change when using OIDC (#2975)
* [chore] Warn about email/password change when using OIDC * go fmt
This commit is contained in:
parent
cc4f773b0e
commit
ce3b8aacf7
|
@ -1541,6 +1541,10 @@ definitions:
|
||||||
$ref: '#/definitions/InstanceConfigurationEmojis'
|
$ref: '#/definitions/InstanceConfigurationEmojis'
|
||||||
media_attachments:
|
media_attachments:
|
||||||
$ref: '#/definitions/instanceConfigurationMediaAttachments'
|
$ref: '#/definitions/instanceConfigurationMediaAttachments'
|
||||||
|
oidc_enabled:
|
||||||
|
description: True if instance is running with OIDC as auth/identity backend, else omitted.
|
||||||
|
type: boolean
|
||||||
|
x-go-name: OIDCEnabled
|
||||||
polls:
|
polls:
|
||||||
$ref: '#/definitions/instanceConfigurationPolls'
|
$ref: '#/definitions/instanceConfigurationPolls'
|
||||||
statuses:
|
statuses:
|
||||||
|
@ -1656,6 +1660,10 @@ definitions:
|
||||||
$ref: '#/definitions/InstanceConfigurationEmojis'
|
$ref: '#/definitions/InstanceConfigurationEmojis'
|
||||||
media_attachments:
|
media_attachments:
|
||||||
$ref: '#/definitions/instanceConfigurationMediaAttachments'
|
$ref: '#/definitions/instanceConfigurationMediaAttachments'
|
||||||
|
oidc_enabled:
|
||||||
|
description: True if instance is running with OIDC as auth/identity backend, else omitted.
|
||||||
|
type: boolean
|
||||||
|
x-go-name: OIDCEnabled
|
||||||
polls:
|
polls:
|
||||||
$ref: '#/definitions/instanceConfigurationPolls'
|
$ref: '#/definitions/instanceConfigurationPolls'
|
||||||
statuses:
|
statuses:
|
||||||
|
@ -9044,6 +9052,8 @@ paths:
|
||||||
description: forbidden
|
description: forbidden
|
||||||
"406":
|
"406":
|
||||||
description: not acceptable
|
description: not acceptable
|
||||||
|
"422":
|
||||||
|
description: unprocessable request because instance is running with OIDC backend
|
||||||
"500":
|
"500":
|
||||||
description: internal error
|
description: internal error
|
||||||
security:
|
security:
|
||||||
|
|
|
@ -157,13 +157,19 @@ When you are finished updating your post settings, remember to click the `Save p
|
||||||
|
|
||||||
You can use the Password Change section of the panel to set a new password for your account. For security reasons, you must provide your current password to validate the change.
|
You can use the Password Change section of the panel to set a new password for your account. For security reasons, you must provide your current password to validate the change.
|
||||||
|
|
||||||
|
!!! info
|
||||||
|
If your instance is using OIDC as its authorization/identity provider, you will not be able to change your password via the GoToSocial settings panel, and you should contact your OIDC provider instead.
|
||||||
|
|
||||||
For more information on the way GoToSocial manages passwords, please see the [Password management document](./password_management.md).
|
For more information on the way GoToSocial manages passwords, please see the [Password management document](./password_management.md).
|
||||||
|
|
||||||
### Email Change
|
### Email Change
|
||||||
|
|
||||||
You can use the Email Change section of the panel to change the email address for your account. For security reasons, you must provide your current password to validate the change.
|
You can use the Email Change section of the panel to change the email address for your account. For security reasons, you must provide your current password to validate the change.
|
||||||
|
|
||||||
Once a new email address has been entered, and you have clicked "Change email address", you must open the inbox of the new email address and confirm your address via the link provided. Once you've done that, your email address change will be confirmed, and you should use the new email address to log in.
|
Once a new email address has been entered, and you have clicked "Change email address", you must open the inbox of the new email address and confirm your address via the link provided. Once you've done that, your email address change will be confirmed.
|
||||||
|
|
||||||
|
!!! info
|
||||||
|
If your instance is using OIDC as its authorization/identity provider, you will be able to change your email address via the settings panel, but it will only affect the email address GoToSocial uses to contact you, it will not change the email address you need to use to log in to your account. To change that, you should contact your OIDC provider.
|
||||||
|
|
||||||
## Migration
|
## Migration
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,13 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const OIDCPasswordHelp = "password change request cannot be processed by GoToSocial as this instance is running with OIDC enabled; you must change password using your OIDC provider"
|
||||||
|
|
||||||
// PasswordChangePOSTHandler swagger:operation POST /api/v1/user/password_change userPasswordChange
|
// PasswordChangePOSTHandler swagger:operation POST /api/v1/user/password_change userPasswordChange
|
||||||
//
|
//
|
||||||
// Change the password of authenticated user.
|
// Change the password of authenticated user.
|
||||||
|
@ -62,6 +65,8 @@ import (
|
||||||
// description: forbidden
|
// description: forbidden
|
||||||
// '406':
|
// '406':
|
||||||
// description: not acceptable
|
// description: not acceptable
|
||||||
|
// '422':
|
||||||
|
// description: unprocessable request because instance is running with OIDC backend
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal error
|
// description: internal error
|
||||||
func (m *Module) PasswordChangePOSTHandler(c *gin.Context) {
|
func (m *Module) PasswordChangePOSTHandler(c *gin.Context) {
|
||||||
|
@ -76,6 +81,12 @@ func (m *Module) PasswordChangePOSTHandler(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.GetOIDCEnabled() {
|
||||||
|
err := errors.New("instance running with OIDC")
|
||||||
|
apiutil.ErrorHandler(c, gtserror.NewErrorUnprocessableEntity(err, OIDCPasswordHelp), m.processor.InstanceGetV1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
form := &apimodel.PasswordChangeRequest{}
|
form := &apimodel.PasswordChangeRequest{}
|
||||||
if err := c.ShouldBind(form); err != nil {
|
if err := c.ShouldBind(form); err != nil {
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
|
||||||
|
|
|
@ -127,4 +127,6 @@ type InstanceV1Configuration struct {
|
||||||
Accounts InstanceConfigurationAccounts `json:"accounts"`
|
Accounts InstanceConfigurationAccounts `json:"accounts"`
|
||||||
// Instance configuration pertaining to emojis.
|
// Instance configuration pertaining to emojis.
|
||||||
Emojis InstanceConfigurationEmojis `json:"emojis"`
|
Emojis InstanceConfigurationEmojis `json:"emojis"`
|
||||||
|
// True if instance is running with OIDC as auth/identity backend, else omitted.
|
||||||
|
OIDCEnabled bool `json:"oidc_enabled,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,6 +163,8 @@ type InstanceV2Configuration struct {
|
||||||
Translation InstanceV2ConfigurationTranslation `json:"translation"`
|
Translation InstanceV2ConfigurationTranslation `json:"translation"`
|
||||||
// Instance configuration pertaining to emojis.
|
// Instance configuration pertaining to emojis.
|
||||||
Emojis InstanceConfigurationEmojis `json:"emojis"`
|
Emojis InstanceConfigurationEmojis `json:"emojis"`
|
||||||
|
// True if instance is running with OIDC as auth/identity backend, else omitted.
|
||||||
|
OIDCEnabled bool `json:"oidc_enabled,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Information about registering for this instance.
|
// Information about registering for this instance.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// GoToSocial
|
// GoToSocial
|
||||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU Affero General Public License as published by
|
// it under the terms of the GNU Affero General Public License as published by
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
@ -4074,4 +4074,3 @@ func GetRequestIDHeader() string { return global.GetRequestIDHeader() }
|
||||||
|
|
||||||
// SetRequestIDHeader safely sets the value for global configuration 'RequestIDHeader' field
|
// SetRequestIDHeader safely sets the value for global configuration 'RequestIDHeader' field
|
||||||
func SetRequestIDHeader(v string) { global.SetRequestIDHeader(v) }
|
func SetRequestIDHeader(v string) { global.SetRequestIDHeader(v) }
|
||||||
|
|
||||||
|
|
|
@ -1328,6 +1328,7 @@ func (c *Converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Ins
|
||||||
instance.Configuration.Accounts.MaxFeaturedTags = instanceAccountsMaxFeaturedTags
|
instance.Configuration.Accounts.MaxFeaturedTags = instanceAccountsMaxFeaturedTags
|
||||||
instance.Configuration.Accounts.MaxProfileFields = instanceAccountsMaxProfileFields
|
instance.Configuration.Accounts.MaxProfileFields = instanceAccountsMaxProfileFields
|
||||||
instance.Configuration.Emojis.EmojiSizeLimit = int(config.GetMediaEmojiLocalMaxSize())
|
instance.Configuration.Emojis.EmojiSizeLimit = int(config.GetMediaEmojiLocalMaxSize())
|
||||||
|
instance.Configuration.OIDCEnabled = config.GetOIDCEnabled()
|
||||||
|
|
||||||
// URLs
|
// URLs
|
||||||
instance.URLs.StreamingAPI = "wss://" + i.Domain
|
instance.URLs.StreamingAPI = "wss://" + i.Domain
|
||||||
|
@ -1467,6 +1468,7 @@ func (c *Converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Ins
|
||||||
instance.Configuration.Accounts.MaxFeaturedTags = instanceAccountsMaxFeaturedTags
|
instance.Configuration.Accounts.MaxFeaturedTags = instanceAccountsMaxFeaturedTags
|
||||||
instance.Configuration.Accounts.MaxProfileFields = instanceAccountsMaxProfileFields
|
instance.Configuration.Accounts.MaxProfileFields = instanceAccountsMaxProfileFields
|
||||||
instance.Configuration.Emojis.EmojiSizeLimit = int(config.GetMediaEmojiLocalMaxSize())
|
instance.Configuration.Emojis.EmojiSizeLimit = int(config.GetMediaEmojiLocalMaxSize())
|
||||||
|
instance.Configuration.OIDCEnabled = config.GetOIDCEnabled()
|
||||||
|
|
||||||
// registrations
|
// registrations
|
||||||
instance.Registrations.Enabled = config.GetAccountsRegistrationOpen()
|
instance.Registrations.Enabled = config.GetAccountsRegistrationOpen()
|
||||||
|
|
|
@ -49,6 +49,7 @@ export interface InstanceConfiguration {
|
||||||
polls: InstancePolls;
|
polls: InstancePolls;
|
||||||
accounts: InstanceAccounts;
|
accounts: InstanceAccounts;
|
||||||
emojis: InstanceEmojis;
|
emojis: InstanceEmojis;
|
||||||
|
oidc_enabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InstanceAccounts {
|
export interface InstanceAccounts {
|
||||||
|
|
|
@ -28,6 +28,7 @@ import { useVerifyCredentialsQuery } from "../../lib/query/oauth";
|
||||||
import { useEmailChangeMutation, usePasswordChangeMutation, useUpdateCredentialsMutation, useUserQuery } from "../../lib/query/user";
|
import { useEmailChangeMutation, usePasswordChangeMutation, useUpdateCredentialsMutation, useUserQuery } from "../../lib/query/user";
|
||||||
import Loading from "../../components/loading";
|
import Loading from "../../components/loading";
|
||||||
import { User } from "../../lib/types/user";
|
import { User } from "../../lib/types/user";
|
||||||
|
import { useInstanceV1Query } from "../../lib/query/gts-api";
|
||||||
|
|
||||||
export default function UserSettings() {
|
export default function UserSettings() {
|
||||||
return (
|
return (
|
||||||
|
@ -106,6 +107,24 @@ function UserSettingsForm({ data }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function PasswordChange() {
|
function PasswordChange() {
|
||||||
|
// Load instance data.
|
||||||
|
const {
|
||||||
|
data: instance,
|
||||||
|
isFetching: isFetchingInstance,
|
||||||
|
isLoading: isLoadingInstance
|
||||||
|
} = useInstanceV1Query();
|
||||||
|
if (isFetchingInstance || isLoadingInstance) {
|
||||||
|
return <Loading />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance === undefined) {
|
||||||
|
throw "could not fetch instance";
|
||||||
|
}
|
||||||
|
|
||||||
|
return <PasswordChangeForm oidcEnabled={instance.configuration.oidc_enabled} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
function PasswordChangeForm({ oidcEnabled }: { oidcEnabled?: boolean }) {
|
||||||
const form = {
|
const form = {
|
||||||
oldPassword: useTextInput("old_password"),
|
oldPassword: useTextInput("old_password"),
|
||||||
newPassword: useTextInput("new_password", {
|
newPassword: useTextInput("new_password", {
|
||||||
|
@ -133,6 +152,13 @@ function PasswordChange() {
|
||||||
<form className="change-password" onSubmit={submitForm}>
|
<form className="change-password" onSubmit={submitForm}>
|
||||||
<div className="form-section-docs">
|
<div className="form-section-docs">
|
||||||
<h3>Change Password</h3>
|
<h3>Change Password</h3>
|
||||||
|
{ oidcEnabled && <p>
|
||||||
|
This instance is running with OIDC as its authorization + identity provider.
|
||||||
|
<br/>
|
||||||
|
This means <strong>you cannot change your password using this settings panel</strong>.
|
||||||
|
<br/>
|
||||||
|
To change your password, you should instead contact your OIDC provider.
|
||||||
|
</p> }
|
||||||
<a
|
<a
|
||||||
href="https://docs.gotosocial.org/en/latest/user_guide/settings/#password-change"
|
href="https://docs.gotosocial.org/en/latest/user_guide/settings/#password-change"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
@ -142,12 +168,14 @@ function PasswordChange() {
|
||||||
Learn more about this (opens in a new tab)
|
Learn more about this (opens in a new tab)
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
type="password"
|
type="password"
|
||||||
name="password"
|
name="password"
|
||||||
field={form.oldPassword}
|
field={form.oldPassword}
|
||||||
label="Current password"
|
label="Current password"
|
||||||
autoComplete="current-password"
|
autoComplete="current-password"
|
||||||
|
disabled={oidcEnabled}
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
type="password"
|
type="password"
|
||||||
|
@ -155,6 +183,7 @@ function PasswordChange() {
|
||||||
field={form.newPassword}
|
field={form.newPassword}
|
||||||
label="New password"
|
label="New password"
|
||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
|
disabled={oidcEnabled}
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
type="password"
|
type="password"
|
||||||
|
@ -162,20 +191,36 @@ function PasswordChange() {
|
||||||
field={verifyNewPassword}
|
field={verifyNewPassword}
|
||||||
label="Confirm new password"
|
label="Confirm new password"
|
||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
|
disabled={oidcEnabled}
|
||||||
/>
|
/>
|
||||||
<MutationButton
|
<MutationButton
|
||||||
disabled={false}
|
|
||||||
label="Change password"
|
label="Change password"
|
||||||
result={result}
|
result={result}
|
||||||
|
disabled={oidcEnabled ?? false}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function EmailChange() {
|
function EmailChange() {
|
||||||
// Load existing user data.
|
// Load instance data.
|
||||||
const { data: user, isFetching, isLoading } = useUserQuery();
|
const {
|
||||||
if (isFetching || isLoading) {
|
data: instance,
|
||||||
|
isFetching: isFetchingInstance,
|
||||||
|
isLoading: isLoadingInstance
|
||||||
|
} = useInstanceV1Query();
|
||||||
|
|
||||||
|
// Load user data.
|
||||||
|
const {
|
||||||
|
data: user,
|
||||||
|
isFetching: isFetchingUser,
|
||||||
|
isLoading: isLoadingUser
|
||||||
|
} = useUserQuery();
|
||||||
|
|
||||||
|
if (
|
||||||
|
(isFetchingInstance || isLoadingInstance) ||
|
||||||
|
(isFetchingUser || isLoadingUser)
|
||||||
|
) {
|
||||||
return <Loading />;
|
return <Loading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,10 +228,14 @@ function EmailChange() {
|
||||||
throw "could not fetch user";
|
throw "could not fetch user";
|
||||||
}
|
}
|
||||||
|
|
||||||
return <EmailChangeForm user={user} />;
|
if (instance === undefined) {
|
||||||
|
throw "could not fetch instance";
|
||||||
|
}
|
||||||
|
|
||||||
|
return <EmailChangeForm user={user} oidcEnabled={instance.configuration.oidc_enabled} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
function EmailChangeForm({user}: {user: User}) {
|
function EmailChangeForm({user, oidcEnabled}: { user: User, oidcEnabled?: boolean }) {
|
||||||
const form = {
|
const form = {
|
||||||
currentEmail: useTextInput("current_email", {
|
currentEmail: useTextInput("current_email", {
|
||||||
defaultValue: user.email,
|
defaultValue: user.email,
|
||||||
|
@ -217,6 +266,15 @@ function EmailChangeForm({user}: {user: User}) {
|
||||||
<form className="change-email" onSubmit={submitForm}>
|
<form className="change-email" onSubmit={submitForm}>
|
||||||
<div className="form-section-docs">
|
<div className="form-section-docs">
|
||||||
<h3>Change Email</h3>
|
<h3>Change Email</h3>
|
||||||
|
{ oidcEnabled && <p>
|
||||||
|
This instance is running with OIDC as its authorization + identity provider.
|
||||||
|
<br/>
|
||||||
|
You can still change your email address using this settings panel,
|
||||||
|
but it will only affect which address GoToSocial uses to contact you,
|
||||||
|
not the email address you use to log in.
|
||||||
|
<br/>
|
||||||
|
To change the email address you use to log in, contact your OIDC provider.
|
||||||
|
</p> }
|
||||||
<a
|
<a
|
||||||
href="https://docs.gotosocial.org/en/latest/user_guide/settings/#email-change"
|
href="https://docs.gotosocial.org/en/latest/user_guide/settings/#email-change"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
@ -227,7 +285,7 @@ function EmailChangeForm({user}: {user: User}) {
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ user.unconfirmed_email && <>
|
{ (user.unconfirmed_email && user.unconfirmed_email !== user.email) && <>
|
||||||
<div className="info">
|
<div className="info">
|
||||||
<i className="fa fa-fw fa-info-circle" aria-hidden="true"></i>
|
<i className="fa fa-fw fa-info-circle" aria-hidden="true"></i>
|
||||||
<b>
|
<b>
|
||||||
|
|
Loading…
Reference in New Issue