feat: send invitation code to backend
This commit is contained in:
@@ -318,6 +318,7 @@ class RegisterUser(BaseModel):
|
|||||||
username: str = Query(default=..., min_length=2, max_length=20)
|
username: str = Query(default=..., min_length=2, max_length=20)
|
||||||
password: str = Query(default=..., min_length=8, max_length=50)
|
password: str = Query(default=..., min_length=8, max_length=50)
|
||||||
password_repeat: str = Query(default=..., min_length=8, max_length=50)
|
password_repeat: str = Query(default=..., min_length=8, max_length=50)
|
||||||
|
invitation_code: str | None = Query(default=None, min_length=1, max_length=256)
|
||||||
|
|
||||||
|
|
||||||
class CreateUser(BaseModel):
|
class CreateUser(BaseModel):
|
||||||
|
|||||||
@@ -366,6 +366,9 @@ async def register(data: RegisterUser) -> JSONResponse:
|
|||||||
if data.email and not is_valid_email_address(data.email):
|
if data.email and not is_valid_email_address(data.email):
|
||||||
raise HTTPException(HTTPStatus.BAD_REQUEST, "Invalid email.")
|
raise HTTPException(HTTPStatus.BAD_REQUEST, "Invalid email.")
|
||||||
|
|
||||||
|
if not await check_register_activation_settings(data):
|
||||||
|
raise HTTPException(HTTPStatus.FORBIDDEN, "User activation failed.")
|
||||||
|
|
||||||
account = Account(
|
account = Account(
|
||||||
id=uuid4().hex,
|
id=uuid4().hex,
|
||||||
email=data.email,
|
email=data.email,
|
||||||
@@ -376,6 +379,21 @@ async def register(data: RegisterUser) -> JSONResponse:
|
|||||||
return _auth_success_response(account.username, account.id, account.email)
|
return _auth_success_response(account.username, account.id, account.email)
|
||||||
|
|
||||||
|
|
||||||
|
async def check_register_activation_settings(data: RegisterUser) -> bool:
|
||||||
|
if not settings.lnbits_require_user_activation:
|
||||||
|
return True
|
||||||
|
if settings.lnbits_user_activation_by_invitation_code and data.invitation_code:
|
||||||
|
code = data.invitation_code.strip()
|
||||||
|
if code == settings.lnbits_register_reusable_activation_code:
|
||||||
|
return True
|
||||||
|
if code in settings.lnbits_register_one_time_activation_codes:
|
||||||
|
settings.lnbits_register_one_time_activation_codes.remove(code)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
@auth_router.put("/pubkey")
|
@auth_router.put("/pubkey")
|
||||||
async def update_pubkey(
|
async def update_pubkey(
|
||||||
data: UpdateUserPubkey,
|
data: UpdateUserPubkey,
|
||||||
|
|||||||
@@ -1197,6 +1197,12 @@ class PublicSettings(BaseModel):
|
|||||||
wallet_featured_button_label: str | None = Field(alias="walletFeaturedButtonLabel")
|
wallet_featured_button_label: str | None = Field(alias="walletFeaturedButtonLabel")
|
||||||
wallet_featured_button_url: str | None = Field(alias="walletFeaturedButtonUrl")
|
wallet_featured_button_url: str | None = Field(alias="walletFeaturedButtonUrl")
|
||||||
wallet_featured_button_icon: str | None = Field(alias="walletFeaturedButtonIcon")
|
wallet_featured_button_icon: str | None = Field(alias="walletFeaturedButtonIcon")
|
||||||
|
lnbits_user_activation_by_email: bool = Field(alias="userActivationByEmail")
|
||||||
|
lnbits_user_activation_by_nostr: bool = Field(alias="userActivationByNostr")
|
||||||
|
lnbits_user_activation_by_payment: bool = Field(alias="userActivationByPayment")
|
||||||
|
lnbits_user_activation_by_invitation_code: bool = Field(
|
||||||
|
alias="userActivationByInvitationCode"
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_settings(cls, settings: Settings):
|
def from_settings(cls, settings: Settings):
|
||||||
@@ -1248,6 +1254,10 @@ class PublicSettings(BaseModel):
|
|||||||
walletFeaturedButtonLabel=settings.lnbits_wallet_featured_button_label,
|
walletFeaturedButtonLabel=settings.lnbits_wallet_featured_button_label,
|
||||||
walletFeaturedButtonUrl=settings.lnbits_wallet_featured_button_url,
|
walletFeaturedButtonUrl=settings.lnbits_wallet_featured_button_url,
|
||||||
walletFeaturedButtonIcon=settings.lnbits_wallet_featured_button_icon,
|
walletFeaturedButtonIcon=settings.lnbits_wallet_featured_button_icon,
|
||||||
|
userActivationByEmail=settings.lnbits_user_activation_by_email,
|
||||||
|
userActivationByNostr=settings.lnbits_user_activation_by_nostr,
|
||||||
|
userActivationByPayment=settings.lnbits_user_activation_by_payment,
|
||||||
|
userActivationByInvitationCode=settings.lnbits_user_activation_by_invitation_code,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -285,7 +285,7 @@ window.localisation.en = {
|
|||||||
'Nip5 identifier to send notifications to',
|
'Nip5 identifier to send notifications to',
|
||||||
notifications_nostr_identifiers: 'Nostr Identifiers',
|
notifications_nostr_identifiers: 'Nostr Identifiers',
|
||||||
notifications_nostr_identifiers_desc:
|
notifications_nostr_identifiers_desc:
|
||||||
'List of identifiers to send notifications to',
|
'List of identifiers to send notifications to.',
|
||||||
|
|
||||||
notifications_telegram_config: 'Telegram Configuration',
|
notifications_telegram_config: 'Telegram Configuration',
|
||||||
notifications_enable_telegram: 'Enable Telegram',
|
notifications_enable_telegram: 'Enable Telegram',
|
||||||
@@ -724,6 +724,9 @@ window.localisation.en = {
|
|||||||
confirmation_code_hint: 'The confirmation code that you have received.',
|
confirmation_code_hint: 'The confirmation code that you have received.',
|
||||||
email: 'Email',
|
email: 'Email',
|
||||||
email_confirmation_hint: 'Email address to send the confirmation code to.',
|
email_confirmation_hint: 'Email address to send the confirmation code to.',
|
||||||
|
nostr_identifier: 'Nostr Identifier',
|
||||||
|
nostr_identifier_hint:
|
||||||
|
'Nostr nip5 identifier or <npub> to send the confirmation code to.',
|
||||||
|
|
||||||
new_user_not_allowed: 'Registration is disabled.',
|
new_user_not_allowed: 'Registration is disabled.',
|
||||||
start_user_impersonation: 'Impersonate this user',
|
start_user_impersonation: 'Impersonate this user',
|
||||||
|
|||||||
@@ -434,6 +434,7 @@ window.app.component('username-password', {
|
|||||||
password_2: String,
|
password_2: String,
|
||||||
resetKey: String
|
resetKey: String
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
oauth: [
|
oauth: [
|
||||||
@@ -449,7 +450,8 @@ window.app.component('username-password', {
|
|||||||
confirmationMethod: 'code',
|
confirmationMethod: 'code',
|
||||||
confirmationEmail: '',
|
confirmationEmail: '',
|
||||||
confirmationCode: '',
|
confirmationCode: '',
|
||||||
showConfirmationCode: false
|
showConfirmationCode: false,
|
||||||
|
nostrConfirmationIdentifier: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -553,6 +555,33 @@ window.app.component('username-password', {
|
|||||||
computed: {
|
computed: {
|
||||||
showOauth() {
|
showOauth() {
|
||||||
return this.oauth.some(m => this.authMethods.includes(m))
|
return this.oauth.some(m => this.authMethods.includes(m))
|
||||||
|
},
|
||||||
|
disableRegister() {
|
||||||
|
const usernameOK = !!this.username
|
||||||
|
const passwordOK = !!this.password && this.password.length >= 8
|
||||||
|
const passwordsMatch = this.password === this.passwordRepeat
|
||||||
|
const codeOk =
|
||||||
|
this.confirmationMethodsCount === 0 ||
|
||||||
|
this.confirmationMethod !== 'code' ||
|
||||||
|
this.confirmationCode.length > 0
|
||||||
|
|
||||||
|
const nostrOk =
|
||||||
|
this.confirmationMethodsCount === 0 ||
|
||||||
|
this.confirmationMethod !== 'nostr' ||
|
||||||
|
this.nostrConfirmationIdentifier.length > 0
|
||||||
|
|
||||||
|
return (
|
||||||
|
!usernameOK || !passwordOK || !passwordsMatch || !codeOk || !nostrOk
|
||||||
|
)
|
||||||
|
},
|
||||||
|
confirmationMethodsCount() {
|
||||||
|
const methods = [
|
||||||
|
this.g.settings.userActivationByEmail,
|
||||||
|
this.g.settings.userActivationByNostr,
|
||||||
|
this.g.settings.userActivationByPayment,
|
||||||
|
this.g.settings.userActivationByInvitationCode
|
||||||
|
]
|
||||||
|
return methods.filter(Boolean).length
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {}
|
created() {}
|
||||||
|
|||||||
@@ -814,20 +814,54 @@ include('components/lnbits-error.vue') %}
|
|||||||
type="password"
|
type="password"
|
||||||
:rules="[val => !val || val.length >= 8 || $t('invalid_password')]"
|
:rules="[val => !val || val.length >= 8 || $t('invalid_password')]"
|
||||||
></q-input>
|
></q-input>
|
||||||
<div class="row justify-center q-mb-md">
|
<div
|
||||||
|
v-if="confirmationMethodsCount > 0"
|
||||||
|
class="q-my-md q-pa-sm text-body2 text-grey-4 bg-grey-9 rounded-borders"
|
||||||
|
>
|
||||||
|
<q-icon name="info" color="orange-4" class="q-mr-xs"></q-icon>
|
||||||
|
|
||||||
|
Confirmation required before you can log in.
|
||||||
|
<div v-if="confirmationMethodsCount > 1">
|
||||||
|
Please choose one of the methods below.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="confirmationMethodsCount > 1"
|
||||||
|
class="row justify-center q-mb-md"
|
||||||
|
>
|
||||||
<q-tabs
|
<q-tabs
|
||||||
v-model="confirmationMethod"
|
v-model="confirmationMethod"
|
||||||
dense
|
dense
|
||||||
active-color="primary"
|
active-color="primary"
|
||||||
indicator-color="primary"
|
indicator-color="primary"
|
||||||
>
|
>
|
||||||
<q-tab name="code" icon="confirmation_number" label="Code"></q-tab>
|
<q-tab
|
||||||
<q-tab name="payment" icon="bolt" label="Payment"></q-tab>
|
v-if="g.settings.userActivationByInvitationCode"
|
||||||
<q-tab name="nostr" icon="bolt" label="Nostr"></q-tab>
|
name="code"
|
||||||
<q-tab name="email" icon="email" label="Email"></q-tab>
|
icon="confirmation_number"
|
||||||
|
label="Code"
|
||||||
|
></q-tab>
|
||||||
|
<q-tab
|
||||||
|
v-if="g.settings.userActivationByPayment"
|
||||||
|
name="payment"
|
||||||
|
icon="bolt"
|
||||||
|
label="Payment"
|
||||||
|
></q-tab>
|
||||||
|
<q-tab
|
||||||
|
v-if="g.settings.userActivationByNostr"
|
||||||
|
name="nostr"
|
||||||
|
icon="bolt"
|
||||||
|
label="Nostr"
|
||||||
|
></q-tab>
|
||||||
|
<q-tab
|
||||||
|
v-if="g.settings.userActivationByEmail"
|
||||||
|
name="email"
|
||||||
|
icon="email"
|
||||||
|
label="Email"
|
||||||
|
></q-tab>
|
||||||
</q-tabs>
|
</q-tabs>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div v-if="confirmationMethodsCount > 0" class="q-mb-md">
|
||||||
<q-tab-panels v-model="confirmationMethod">
|
<q-tab-panels v-model="confirmationMethod">
|
||||||
<q-tab-panel name="code" class="q-pa-none">
|
<q-tab-panel name="code" class="q-pa-none">
|
||||||
<div>
|
<div>
|
||||||
@@ -854,8 +888,17 @@ include('components/lnbits-error.vue') %}
|
|||||||
<q-tab-panel name="payment">
|
<q-tab-panel name="payment">
|
||||||
<div>payment</div>
|
<div>payment</div>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
<q-tab-panel name="nostr">
|
<q-tab-panel name="nostr" class="q-pa-none">
|
||||||
<div>nostr</div>
|
<div>
|
||||||
|
<q-input
|
||||||
|
dense
|
||||||
|
filled
|
||||||
|
v-model="nostrConfirmationIdentifier"
|
||||||
|
:label="$t('nostr_identifier')"
|
||||||
|
:hint="$t('nostr_identifier_hint')"
|
||||||
|
>
|
||||||
|
</q-input>
|
||||||
|
</div>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
<q-tab-panel name="email" class="q-pa-none">
|
<q-tab-panel name="email" class="q-pa-none">
|
||||||
<div>
|
<div>
|
||||||
@@ -876,12 +919,7 @@ include('components/lnbits-error.vue') %}
|
|||||||
<q-btn
|
<q-btn
|
||||||
unelevated
|
unelevated
|
||||||
color="primary"
|
color="primary"
|
||||||
:disable="
|
:disable="disableRegister"
|
||||||
!password ||
|
|
||||||
!passwordRepeat ||
|
|
||||||
!username ||
|
|
||||||
password !== passwordRepeat
|
|
||||||
"
|
|
||||||
type="submit"
|
type="submit"
|
||||||
class="full-width"
|
class="full-width"
|
||||||
:label="$t('create_account')"
|
:label="$t('create_account')"
|
||||||
|
|||||||
@@ -281,7 +281,6 @@
|
|||||||
<div class="row items-center">
|
<div class="row items-center">
|
||||||
<q-toggle
|
<q-toggle
|
||||||
size="md"
|
size="md"
|
||||||
disable
|
|
||||||
:label="
|
:label="
|
||||||
formData.lnbits_user_activation_by_nostr
|
formData.lnbits_user_activation_by_nostr
|
||||||
? $t('enabled')
|
? $t('enabled')
|
||||||
|
|||||||
Reference in New Issue
Block a user