mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
Improve flows for social auth users (#13862)
* Multiple fixes for social authentication flows * frontend changes * add missing computed property * Improvements to social flows * fix existing email error * minor fixes * fix space * fix test * fix lint Co-authored-by: SabreCat <sabe@habitica.com>
This commit is contained in:
@@ -84,8 +84,8 @@
|
||||
</li>
|
||||
<li v-if="user">
|
||||
<a
|
||||
@click.prevent="openBugReportModal()"
|
||||
target="_blank"
|
||||
@click.prevent="openBugReportModal()"
|
||||
>
|
||||
{{ $t('reportBug') }}
|
||||
</a>
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="form-group row text-center"
|
||||
v-if="!registering"
|
||||
class="form-group row text-center"
|
||||
>
|
||||
<div class="col-12 col-md-12">
|
||||
<div
|
||||
@@ -269,13 +269,13 @@
|
||||
<label
|
||||
v-once
|
||||
for="usernameInput"
|
||||
>{{ $t('email') }}</label>
|
||||
>{{ $t('emailOrUsername') }}</label>
|
||||
<input
|
||||
id="usernameInput"
|
||||
v-model="username"
|
||||
class="form-control"
|
||||
type="text"
|
||||
:placeholder="$t('emailPlaceholder')"
|
||||
:placeholder="$t('emailUsernamePlaceholder')"
|
||||
>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
|
||||
@@ -12,12 +12,18 @@
|
||||
{{ $t('reportBug') }}
|
||||
</h2>
|
||||
|
||||
<div v-once class="report-bug-header-describe">
|
||||
<div
|
||||
v-once
|
||||
class="report-bug-header-describe"
|
||||
>
|
||||
{{ $t('reportBugHeaderDescribe') }}
|
||||
</div>
|
||||
|
||||
<div class="dialog-close">
|
||||
<close-icon @click="close()" :purple="true"/>
|
||||
<close-icon
|
||||
:purple="true"
|
||||
@click="close()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
@@ -34,7 +40,10 @@
|
||||
>
|
||||
{{ $t('email') }}
|
||||
</label>
|
||||
<div class="mb-2 description-label" v-once>
|
||||
<div
|
||||
v-once
|
||||
class="mb-2 description-label"
|
||||
>
|
||||
{{ $t('reportEmailText') }}
|
||||
</div>
|
||||
<input
|
||||
@@ -47,7 +56,10 @@
|
||||
:class="{'input-invalid': emailInvalid, 'input-valid': emailValid}"
|
||||
>
|
||||
|
||||
<div class="error-label mt-2" v-if="emailInvalid">
|
||||
<div
|
||||
v-if="emailInvalid"
|
||||
class="error-label mt-2"
|
||||
>
|
||||
{{ $t('reportEmailError') }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,7 +67,10 @@
|
||||
<label v-once>
|
||||
{{ $t('reportDescription') }}
|
||||
</label>
|
||||
<div class="mb-2 description-label" v-once>
|
||||
<div
|
||||
v-once
|
||||
class="mb-2 description-label"
|
||||
>
|
||||
{{ $t('reportDescriptionText') }}
|
||||
</div>
|
||||
<textarea
|
||||
|
||||
@@ -17,15 +17,22 @@
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span class="svg-icon check-icon"
|
||||
<span
|
||||
class="svg-icon check-icon"
|
||||
v-html="icons.checkCircleIcon"
|
||||
></span>
|
||||
|
||||
<div class="title" v-once>
|
||||
<div
|
||||
v-once
|
||||
class="title"
|
||||
>
|
||||
{{ $t('reportSent') }}
|
||||
</div>
|
||||
|
||||
<div class="text mt-3 mb-4" v-once>
|
||||
<div
|
||||
v-once
|
||||
class="text mt-3 mb-4"
|
||||
>
|
||||
{{ $t('reportSentDescription') }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -143,12 +150,12 @@ export default {
|
||||
modalId: MODALS.BUG_REPORT_SUCCESS,
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
mounted () {},
|
||||
methods: {
|
||||
close () {
|
||||
this.$root.$emit('bv::hide::modal', MODALS.BUG_REPORT_SUCCESS);
|
||||
},
|
||||
},
|
||||
computed: {},
|
||||
mounted () {},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -361,8 +361,8 @@
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
@click.prevent="openBugReportModal()"
|
||||
target="_blank"
|
||||
@click.prevent="openBugReportModal()"
|
||||
>
|
||||
{{ $t('reportBug') }}
|
||||
</a>
|
||||
|
||||
@@ -311,8 +311,8 @@
|
||||
</router-link>
|
||||
<a
|
||||
class="topbar-dropdown-item dropdown-item"
|
||||
@click.prevent="openBugReportModal()"
|
||||
target="_blank"
|
||||
@click.prevent="openBugReportModal()"
|
||||
>
|
||||
{{ $t('reportBug') }}
|
||||
</a>
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
>
|
||||
<div class="modal-body">
|
||||
<br>
|
||||
<strong v-if="user.auth.local.email">{{ $t('deleteLocalAccountText') }}</strong>
|
||||
<strong v-if="user.auth.local.has_password">{{ $t('deleteLocalAccountText') }}</strong>
|
||||
<strong
|
||||
v-if="!user.auth.local.email"
|
||||
v-if="!user.auth.local.has_password"
|
||||
>{{ $t('deleteSocialAccountText', {magicWord: 'DELETE'}) }}</strong>
|
||||
<div class="row mt-3">
|
||||
<div class="col-6">
|
||||
|
||||
@@ -291,14 +291,22 @@
|
||||
</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<div v-if="!user.auth.local.email">
|
||||
<p>{{ $t('addLocalAuth') }}</p>
|
||||
<div v-if="!user.auth.local.has_password">
|
||||
<h5 v-if="!user.auth.local.email">
|
||||
{{ $t('addLocalAuth') }}
|
||||
</h5>
|
||||
<h5 v-if="user.auth.local.email">
|
||||
{{ $t('addPasswordAuth') }}
|
||||
</h5>
|
||||
<div
|
||||
class="form"
|
||||
name="localAuth"
|
||||
novalidate="novalidate"
|
||||
>
|
||||
<div class="form-group">
|
||||
<div
|
||||
v-if="!user.auth.local.email"
|
||||
class="form-group"
|
||||
>
|
||||
<input
|
||||
v-model="localAuth.email"
|
||||
class="form-control"
|
||||
@@ -421,7 +429,7 @@
|
||||
{{ $t('saveAndConfirm') }}
|
||||
</button>
|
||||
</div>
|
||||
<h5 v-if="user.auth.local.email">
|
||||
<h5>
|
||||
{{ $t('changeEmail') }}
|
||||
</h5>
|
||||
<div
|
||||
@@ -439,7 +447,10 @@
|
||||
:placeholder="$t('newEmail')"
|
||||
>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div
|
||||
v-if="user.auth.local.has_password"
|
||||
class="form-group"
|
||||
>
|
||||
<input
|
||||
v-model="emailUpdates.password"
|
||||
class="form-control"
|
||||
@@ -455,11 +466,11 @@
|
||||
{{ $t('submit') }}
|
||||
</button>
|
||||
</div>
|
||||
<h5 v-if="user.auth.local.email">
|
||||
<h5 v-if="user.auth.local.has_password">
|
||||
{{ $t('changePass') }}
|
||||
</h5>
|
||||
<div
|
||||
v-if="user.auth.local.email"
|
||||
v-if="user.auth.local.has_password"
|
||||
class="form"
|
||||
name="changePassword"
|
||||
novalidate="novalidate"
|
||||
@@ -846,7 +857,7 @@ export default {
|
||||
if (network === 'apple') {
|
||||
window.location.href = buildAppleAuthUrl();
|
||||
} else {
|
||||
const auth = await hello(network).login({ scope: 'email' });
|
||||
const auth = await hello(network).login({ scope: 'email', options: { force: true } });
|
||||
|
||||
await this.$store.dispatch('auth:socialAuth', {
|
||||
auth,
|
||||
@@ -865,8 +876,12 @@ export default {
|
||||
}
|
||||
},
|
||||
async addLocalAuth () {
|
||||
if (this.localAuth.email === '') {
|
||||
this.localAuth.email = this.user.auth.local.email;
|
||||
}
|
||||
await axios.post('/api/v4/user/auth/local/register', this.localAuth);
|
||||
window.alert(this.$t('addedLocalAuth')); // eslint-disable-line no-alert
|
||||
window.location.href = '/';
|
||||
},
|
||||
restoreEmptyUsername () {
|
||||
if (this.usernameUpdates.username.length < 1) {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<button
|
||||
title="close dialog"
|
||||
@click="$emit('click', $event)"
|
||||
:style="{
|
||||
'--icon-color': iconColor,
|
||||
'--icon-color-hover': iconColorHover,
|
||||
}"
|
||||
:class="{'purple': purple}"
|
||||
@click="$emit('click', $event)"
|
||||
>
|
||||
<div
|
||||
v-once
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
<span v-if="user">
|
||||
<br>
|
||||
<a
|
||||
@click.prevent="openBugReportModal()"
|
||||
target="_blank"
|
||||
@click.prevent="openBugReportModal()"
|
||||
>
|
||||
{{ $t('reportBug') }}
|
||||
</a>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<p>
|
||||
HabitRPG, Inc. (“HabitRPG,” “we,” “us,” or “our”) welcomes you. This privacy notice (the “Privacy
|
||||
Notice”) describes how we process the information we collect about or from you through our Website
|
||||
located at <a href='https://habitica.com/static/home'>https://habitica.com/static/home</a> and/or our Apps
|
||||
located at <a href="https://habitica.com/static/home">https://habitica.com/static/home</a> and/or our Apps
|
||||
(our “Digital Platforms”), from our users, subscribers, visitors and other users of our technology and
|
||||
platforms (together with our Digital Platforms, the “Habitica Service” or the “Service”), and when you
|
||||
otherwise interact with us. This Privacy Notice may be updated by us from time to time without notice to
|
||||
@@ -65,11 +65,36 @@
|
||||
policies linked to below:
|
||||
</p>
|
||||
<ul>
|
||||
<li>For Stripe, visit: <a href='https://stripe.com/privacy' target='_blank'>https://stripe.com/privacy</a></li>
|
||||
<li>For Amazon Pay, visit: <a href='https://pay.amazon.com/help/201751600' target='_blank'>https://pay.amazon.com/help/201751600</a></li>
|
||||
<li>For PayPal, visit: <a href='https://www.paypal.com/us/webapps/mpp/ua/privacy-full' target='_blank'>https://www.paypal.com/us/webapps/mpp/ua/privacy-full</a></li>
|
||||
<li>For Apple Pay, visit: <a href='https://www.apple.com/legal/privacy/data/en/apple-pay/' target='_blank'>https://www.apple.com/legal/privacy/data/en/apple-pay/</a></li>
|
||||
<li>For Google Pay, visit: <a href='https://support.google.com/googlepay/answer/10223752?hl=en&co=GENIE.Platform%3DAndroid' target='_blank'>https://support.google.com/googlepay/answer/10223752?hl=en&co=GENIE.Platform%3DAndroid</a></li>
|
||||
<li>
|
||||
For Stripe, visit: <a
|
||||
href="https://stripe.com/privacy"
|
||||
target="_blank"
|
||||
>https://stripe.com/privacy</a>
|
||||
</li>
|
||||
<li>
|
||||
For Amazon Pay, visit: <a
|
||||
href="https://pay.amazon.com/help/201751600"
|
||||
target="_blank"
|
||||
>https://pay.amazon.com/help/201751600</a>
|
||||
</li>
|
||||
<li>
|
||||
For PayPal, visit: <a
|
||||
href="https://www.paypal.com/us/webapps/mpp/ua/privacy-full"
|
||||
target="_blank"
|
||||
>https://www.paypal.com/us/webapps/mpp/ua/privacy-full</a>
|
||||
</li>
|
||||
<li>
|
||||
For Apple Pay, visit: <a
|
||||
href="https://www.apple.com/legal/privacy/data/en/apple-pay/"
|
||||
target="_blank"
|
||||
>https://www.apple.com/legal/privacy/data/en/apple-pay/</a>
|
||||
</li>
|
||||
<li>
|
||||
For Google Pay, visit: <a
|
||||
href="https://support.google.com/googlepay/answer/10223752?hl=en&co=GENIE.Platform%3DAndroid"
|
||||
target="_blank"
|
||||
>https://support.google.com/googlepay/answer/10223752?hl=en&co=GENIE.Platform%3DAndroid</a>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
We reserve the right to change our payment vendors at any time, or to use additional payment vendors, at
|
||||
@@ -95,22 +120,32 @@
|
||||
see the information regarding analytics providers discussed further below.
|
||||
</p>
|
||||
<ul>
|
||||
<li><strong>Session Cookies</strong>: We use session cookies to make it easier for you to navigate our Service. A
|
||||
session ID cookie expires when you close the Service.</li>
|
||||
<li><strong>Persistent Cookies</strong>: A persistent cookie remains on your device for an extended period of time or
|
||||
<li>
|
||||
<strong>Session Cookies</strong>: We use session cookies to make it easier for you to navigate our Service. A
|
||||
session ID cookie expires when you close the Service.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Persistent Cookies</strong>: A persistent cookie remains on your device for an extended period of time or
|
||||
until you delete it. Persistent cookies enable us to better understand how you interact with the Service and to
|
||||
provide visitors with a better and more personalized experience by retaining information about their identity and
|
||||
preferences, including but not limited to keeping them logged in even if the browser is closed.</li>
|
||||
preferences, including but not limited to keeping them logged in even if the browser is closed.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
If you do not want us to place a cookie on your device, you may be able to turn that feature off on your
|
||||
device. You may refuse to accept cookies from the Service at any time by activating the setting on your
|
||||
browser which allows you to refuse cookies. Further information about the procedure to follow in order to
|
||||
disable cookies can be found on your Internet browser provider’s website via your help screen. You may
|
||||
wish to refer to <a href='http://www.allaboutcookies.org/manage-cookies/index.html' target='_blank'>
|
||||
wish to refer to <a
|
||||
href="http://www.allaboutcookies.org/manage-cookies/index.html"
|
||||
target="_blank"
|
||||
>
|
||||
http://www.allaboutcookies.org/manage-cookies/index.html</a> for information on commonly used browsers.
|
||||
For more information about targeting and advertising cookies and how you can opt out, you can also visit
|
||||
<a href='http://optout.aboutads.info' target='_blank'>http://optout.aboutads.info</a>. Please be aware
|
||||
<a
|
||||
href="http://optout.aboutads.info"
|
||||
target="_blank"
|
||||
>http://optout.aboutads.info</a>. Please be aware
|
||||
that if cookies are disabled, not all features of the Service may operate properly or as intended.
|
||||
</p>
|
||||
<h3>Third-Party Analytics Providers</h3>
|
||||
@@ -129,8 +164,18 @@
|
||||
advised that if you opt out of any service, you may not be able to use the full functionality of the Service.
|
||||
</p>
|
||||
<ul>
|
||||
<li>For Google Analytics, visit: <a href='https://marketingplatform.google.com/about/analytics/' target='_blank'>https://marketingplatform.google.com/about/analytics/</a></li>
|
||||
<li>For Amplitude, visit: <a href='https://amplitude.com/privacy' target='_blank'>https://amplitude.com/privacy</a></li>
|
||||
<li>
|
||||
For Google Analytics, visit: <a
|
||||
href="https://marketingplatform.google.com/about/analytics/"
|
||||
target="_blank"
|
||||
>https://marketingplatform.google.com/about/analytics/</a>
|
||||
</li>
|
||||
<li>
|
||||
For Amplitude, visit: <a
|
||||
href="https://amplitude.com/privacy"
|
||||
target="_blank"
|
||||
>https://amplitude.com/privacy</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Third-Party Advertisers/Remarketers</h3>
|
||||
<p>
|
||||
@@ -150,7 +195,9 @@
|
||||
</p>
|
||||
<p>
|
||||
For more information on our advertising partner Google AdMob, please visit <a
|
||||
href='https://policies.google.com/privacy?hl=en' target='_blank'>https://policies.google.com/privacy?hl=en</a>.
|
||||
href="https://policies.google.com/privacy?hl=en"
|
||||
target="_blank"
|
||||
>https://policies.google.com/privacy?hl=en</a>.
|
||||
</p>
|
||||
<h3>Geolocation Information</h3>
|
||||
<p>
|
||||
@@ -229,7 +276,7 @@
|
||||
</p>
|
||||
<p>
|
||||
You may opt out at any time from the use of your personal information for direct marketing purposes by
|
||||
emailing the instructions to <a href='mailto:admin@habitica.com'>admin@habitica.com</a> or by clicking
|
||||
emailing the instructions to <a href="mailto:admin@habitica.com">admin@habitica.com</a> or by clicking
|
||||
on the “Unsubscribe” link located on the bottom of any HabitRPG marketing email and following the
|
||||
instructions found on the page to which the link takes you. Please allow us a reasonable time to process
|
||||
your request. You cannot opt out of receiving transactional e-mails related to the Service.
|
||||
@@ -274,7 +321,7 @@
|
||||
direct marketing purposes during the preceding calendar year, including the names and addresses of those
|
||||
third parties, and examples of the types of Service or products marketed by those third parties. If you wish
|
||||
to submit a request pursuant to Section 1798.83, please contact HabitRPG via email at
|
||||
<a href='mailto:admin@habitica.com'>admin@habitica.com</a>.
|
||||
<a href="mailto:admin@habitica.com">admin@habitica.com</a>.
|
||||
</p>
|
||||
<h2>NEVADA PRIVACY RIGHTS</h2>
|
||||
<p>
|
||||
@@ -306,7 +353,7 @@
|
||||
</p>
|
||||
<h2>HOW TO CONTACT US</h2>
|
||||
<p>
|
||||
If you have questions about this Privacy Notice, please e-mail us at <a href='mailto:admin@habitica.com'>
|
||||
If you have questions about this Privacy Notice, please e-mail us at <a href="mailto:admin@habitica.com">
|
||||
admin@habitica.com</a> with “Privacy Notice” in the subject line.
|
||||
</p>
|
||||
<address>
|
||||
|
||||
@@ -2,11 +2,20 @@
|
||||
<!-- eslint-disable max-len -->
|
||||
<div class="container-fluid">
|
||||
<h1>Terms of Service</h1>
|
||||
<p class="strong pagemeta">Last Updated: December 14, 2021</p>
|
||||
<p class="strong pagemeta">
|
||||
Last Updated: December 14, 2021
|
||||
</p>
|
||||
<p>Thanks for choosing Habitica!</p>
|
||||
<p>Our Service is provided by HabitRPG, Inc. ("HabitRPG"). By accepting these Terms of Service and our Privacy Policy located at: <a href="https://habitica.com/static/privacy" target="_blank">https://habitica.com/static/privacy</a> (collectively, the "Agreement"), registering for the Service (as defined below), accessing or using any part of the Service, or otherwise manifesting your assent to the Agreement, you acknowledge that you have read, understood, and agree to be legally bound by the Agreement. If you do not agree to (or cannot comply with) the Agreement, you are not permitted to access or use the Service.</p>
|
||||
<p>
|
||||
Our Service is provided by HabitRPG, Inc. ("HabitRPG"). By accepting these Terms of Service and our Privacy Policy located at: <a
|
||||
href="https://habitica.com/static/privacy"
|
||||
target="_blank"
|
||||
>https://habitica.com/static/privacy</a> (collectively, the "Agreement"), registering for the Service (as defined below), accessing or using any part of the Service, or otherwise manifesting your assent to the Agreement, you acknowledge that you have read, understood, and agree to be legally bound by the Agreement. If you do not agree to (or cannot comply with) the Agreement, you are not permitted to access or use the Service.
|
||||
</p>
|
||||
<p>By accepting or agreeing to this Agreement on behalf of a company or other legal entity, you represent and warrant that you have the authority to bind that company or other legal entity to the Agreement and, in such event, "you" and "your" will refer and apply to that company or other legal entity.</p>
|
||||
<p class="strong">THE SECTIONS BELOW TITLED "BINDING ARBITRATION," AND "CLASS ACTION WAIVER" CONTAIN A BINDING ARBITRATION AGREEMENT AND CLASS ACTION WAIVER. THEY AFFECT YOUR LEGAL RIGHTS. PLEASE READ THEM.</p>
|
||||
<p class="strong">
|
||||
THE SECTIONS BELOW TITLED "BINDING ARBITRATION," AND "CLASS ACTION WAIVER" CONTAIN A BINDING ARBITRATION AGREEMENT AND CLASS ACTION WAIVER. THEY AFFECT YOUR LEGAL RIGHTS. PLEASE READ THEM.
|
||||
</p>
|
||||
<h2>Changes to the Terms of Service</h2>
|
||||
<p>These Terms of Service are effective as of the last updated date stated at the top of this page. We may change these Terms of Service from time to time with or without notice to you. By accessing the Service after we make any such changes to this Terms of Service, you are deemed to have accepted such changes. Please be aware that, to the extent permitted by applicable law, our use of the information collected is governed by the Terms of Service in effect at the time we collect the information. Please refer back to this Terms of Service on a regular basis.</p>
|
||||
<p>Our Service allows you to upload, store, send, download, or receive content, including but not limited to information, text, graphics, artwork, or other material ("Content"). You retain ownership of any intellectual property rights that you have in your Content. You hereby grant HabitRPG a worldwide, perpetual, irrevocable, sublicenseable, transferable, assignable, non-exclusive, and royalty-free right and license to use, reproduce, distribute, adapt, modify, translate, create derivative works of, publicly perform, publicly display, digitally perform, make, have made, sell, offer for sale, and import your Content, including all intellectual property rights therein. You represent, warrant, and agree that your Content does not and will not violate any third-party intellectual property, privacy, or other rights, and that you have all right, title and interest in and to your Content required to grant us the license above. We reserve the right at all times, but have no obligation, to delete or refuse to use or distribute any Content on or through the Service, including your Content.</p>
|
||||
@@ -59,7 +68,12 @@
|
||||
<p>You will be charged the amount shown on Pricing before you can access Premium Service. All prices shown on Pricing are inclusive of any applicable sales taxes, levies, value-added taxes, or duties imposed by taxing authorities, and you are responsible for payment of all such taxes, levies, or duties. We may revise the Pricing at any time and may, from time to time, modify, amend, or supplement our fees and fee-billing methods. Such changes shall be effective upon posting on the Pricing page or elsewhere in the Service. If there is a dispute regarding payment of fees to us, we reserve the right to terminate or suspend your account at our sole discretion.</p>
|
||||
<p>BY PURCHASING PREMIUM YOU EXPRESSLY UNDERSTAND AND AGREE TO OUR REFUND POLICY:</p>
|
||||
<p>WITHIN THIRTY (30) DAYS OF YOUR PREMIUM PAYMENT DATE AS SHOWN ON YOUR PAYMENT BILL, YOU CAN REQUEST A FULL REFUND BY CONTACTING US AT ADMIN@HABITICA.COM. AFTER THIRTY (30) DAYS OF YOUR PREMIUM PAYMENT DATE, ANY PAYMENT REFUND IS SOLELY SUBJECT TO OUR DISCRETION. THE REFUND SHALL BE YOUR SOLE AND EXCLUSIVE REMEDY.</p>
|
||||
<p>FOR ANY CUSTOMER WHO PURCHASED PREMIUM IN APPLE INC.'s APP STORE ("APP STORE"), PLEASE CONTACT APPLE INC.'s SUPPORT TEAM: <a href="http://reportaproblem.apple.com" target="_blank">http://reportaproblem.apple.com</a>. APPLE'S APP STORE DOES NOT ALLOW DEVELOPERS TO ISSUE REFUND FOR APP STORE PURCHASES MADE BY CUSTOMERS.</p>
|
||||
<p>
|
||||
FOR ANY CUSTOMER WHO PURCHASED PREMIUM IN APPLE INC.'s APP STORE ("APP STORE"), PLEASE CONTACT APPLE INC.'s SUPPORT TEAM: <a
|
||||
href="http://reportaproblem.apple.com"
|
||||
target="_blank"
|
||||
>http://reportaproblem.apple.com</a>. APPLE'S APP STORE DOES NOT ALLOW DEVELOPERS TO ISSUE REFUND FOR APP STORE PURCHASES MADE BY CUSTOMERS.
|
||||
</p>
|
||||
<h2>Warranty Disclaimer</h2>
|
||||
<p>THE SERVICE AND ANY CONTENT MADE AVAILABLE BY HABITRPG VIA THE SERVICE IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT ANY WARRANTIES OF ANY KIND, INCLUDING, WITHOUT LIMITATION, THAT THE SERVICE OR CONTENT WILL OPERATE ERROR-FREE OR THAT THE SERVICE OR CONTENT OR ITS SERVERS ARE FREE OF COMPUTER VIRUSES OR SIMILAR CONTAMINATION OR DESTRUCTIVE FEATURES.</p>
|
||||
<p>WE DISCLAIM ALL WARRANTIES, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF TITLE, MERCHANTABILITY, NON-INFRINGEMENT OF THIRD PARTIES' RIGHTS, AND FITNESS FOR PARTICULAR PURPOSE AND ANY WARRANTIES ARISING FROM A COURSE OF DEALING, COURSE OF PERFORMANCE, OR USAGE OF TRADE.</p>
|
||||
@@ -71,7 +85,12 @@
|
||||
<h2>Compliance with Applicable Laws</h2>
|
||||
<p>The Service is based in the United States. We make no claims concerning whether the Service or posted content may be downloaded, viewed, or be appropriate for use outside of the United States. If you access the Service or such content from outside of the United States, you do so at your own risk. Whether inside or outside of the United States, you are solely responsible for ensuring compliance with the laws of your specific jurisdiction.</p>
|
||||
<h2>Binding Arbitration</h2>
|
||||
<p>In the event of a dispute arising under or relating to this Agreement or the Service (each, a "<u>Dispute</u>"), such dispute will be finally and exclusively resolved by binding arbitration governed by the Federal Arbitration Act ("<u>FAA</u>"). Any election to arbitrate, at any time, shall be final and binding on the other party. NEITHER PARTY SHALL HAVE THE RIGHT TO LITIGATE SUCH CLAIM IN COURT OR TO HAVE A JURY TRIAL, EXCEPT EITHER PARTY MAY BRING ITS CLAIM IN ITS LOCAL SMALL CLAIMS COURT, IF PERMITTED BY THAT SMALL CLAIMS COURT RULES AND IF WITHIN SUCH COURT'S JURISDICTION. ARBITRATION IS DIFFERENT FROM COURT, AND DISCOVERY AND APPEAL RIGHTS MAY ALSO BE LIMITED IN ARBITRATION. All disputes will be resolved before a neutral arbitrator selected jointly by the parties, whose decision will be final, except for a limited right of appeal under the FAA. The arbitration shall be commenced and conducted by JAMS pursuant to its then current Comprehensive Arbitration Rules and Procedures and in accordance with the Expedited Procedures in those rules, or, where appropriate, pursuant to JAMS' Streamlined Arbitration Rules and Procedures. All applicable JAMS' rules and procedures are available at the JAMS website <a href="https://www.jamsadr.com" target="_blank">www.jamsadr.com</a>. Each party will be responsible for paying any JAMS filing, administrative, and arbitrator fees in accordance with JAMS rules. Judgment on the arbitrator's award may be entered in any court having jurisdiction. This clause shall not preclude parties from seeking provisional remedies in aid of arbitration from a court of appropriate jurisdiction. The arbitration may be conducted in person, through the submission of documents, by phone, or online. If conducted in person, the arbitration shall take place in the United States county where you reside. The parties may litigate in court to compel arbitration, to stay a proceeding pending arbitration, or to confirm, modify, vacate, or enter judgment on the award entered by the arbitrator. The parties shall cooperate in good faith in the voluntary and informal exchange of all non-privileged documents and other information (including electronically stored information) relevant to the Dispute immediately after commencement of the arbitration. As set forth below, nothing in this Agreement will prevent us from seeking injunctive relief in any court of competent jurisdiction as necessary to protect our proprietary interests.</p>
|
||||
<p>
|
||||
In the event of a dispute arising under or relating to this Agreement or the Service (each, a "<u>Dispute</u>"), such dispute will be finally and exclusively resolved by binding arbitration governed by the Federal Arbitration Act ("<u>FAA</u>"). Any election to arbitrate, at any time, shall be final and binding on the other party. NEITHER PARTY SHALL HAVE THE RIGHT TO LITIGATE SUCH CLAIM IN COURT OR TO HAVE A JURY TRIAL, EXCEPT EITHER PARTY MAY BRING ITS CLAIM IN ITS LOCAL SMALL CLAIMS COURT, IF PERMITTED BY THAT SMALL CLAIMS COURT RULES AND IF WITHIN SUCH COURT'S JURISDICTION. ARBITRATION IS DIFFERENT FROM COURT, AND DISCOVERY AND APPEAL RIGHTS MAY ALSO BE LIMITED IN ARBITRATION. All disputes will be resolved before a neutral arbitrator selected jointly by the parties, whose decision will be final, except for a limited right of appeal under the FAA. The arbitration shall be commenced and conducted by JAMS pursuant to its then current Comprehensive Arbitration Rules and Procedures and in accordance with the Expedited Procedures in those rules, or, where appropriate, pursuant to JAMS' Streamlined Arbitration Rules and Procedures. All applicable JAMS' rules and procedures are available at the JAMS website <a
|
||||
href="https://www.jamsadr.com"
|
||||
target="_blank"
|
||||
>www.jamsadr.com</a>. Each party will be responsible for paying any JAMS filing, administrative, and arbitrator fees in accordance with JAMS rules. Judgment on the arbitrator's award may be entered in any court having jurisdiction. This clause shall not preclude parties from seeking provisional remedies in aid of arbitration from a court of appropriate jurisdiction. The arbitration may be conducted in person, through the submission of documents, by phone, or online. If conducted in person, the arbitration shall take place in the United States county where you reside. The parties may litigate in court to compel arbitration, to stay a proceeding pending arbitration, or to confirm, modify, vacate, or enter judgment on the award entered by the arbitrator. The parties shall cooperate in good faith in the voluntary and informal exchange of all non-privileged documents and other information (including electronically stored information) relevant to the Dispute immediately after commencement of the arbitration. As set forth below, nothing in this Agreement will prevent us from seeking injunctive relief in any court of competent jurisdiction as necessary to protect our proprietary interests.
|
||||
</p>
|
||||
<p>ANY CLAIMS, ACTIONS OR PROCEEDINGS BY YOU MUST BE COMMENCED WITHIN ONE YEAR AFTER THE EVENT THAT GAVE RISE TO YOUR CLAIM OCCURS. ALL OTHER CLAIMS YOU MAY HAVE ARE PERMANENTLY BARRED.</p>
|
||||
<h2>Class Action Waiver</h2>
|
||||
<p>You agree that any arbitration or proceeding shall be limited to the Dispute between us and you individually. To the full extent permitted by law, (i) no arbitration or proceeding shall be joined with any other; (ii) there is no right or authority for any Dispute to be arbitrated or resolved on a class action-basis or to utilize class action procedures; and (iii) there is no right or authority for any Dispute to be brought in a purported representative capacity on behalf of the general public or any other persons. YOU AGREE THAT YOU MAY BRING CLAIMS AGAINST US ONLY IN YOUR INDIVIDUAL CAPACITY AND NOT AS A PLAINTIFF OR CLASS MEMBER IN ANY PURPORTED CLASS OR REPRESENTATIVE PROCEEDING.</p>
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
"addedLocalAuth": "Successfully added local authentication",
|
||||
"data": "Δεδομένα",
|
||||
"email": "Email",
|
||||
"emailOrUsername": "Username or Email",
|
||||
"registerWithSocial": "Register with <%= network %>",
|
||||
"registeredWithSocial": "Registered with <%= network %>",
|
||||
"emailNotifications": "Ειδοποιήσεις email",
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"companyDonate": "Donate",
|
||||
"forgotPassword": "Forgot Password?",
|
||||
"emailNewPass": "Email a Password Reset Link",
|
||||
"forgotPasswordSteps": "Enter the email address you used to register your Habitica account.",
|
||||
"forgotPasswordSteps": "Enter your username or the email address you used to register your Habitica account.",
|
||||
"sendLink": "Send Link",
|
||||
"footerDevs": "Developers",
|
||||
"footerCommunity": "Community",
|
||||
@@ -125,7 +125,7 @@
|
||||
"passwordConfirmationMatch": "Password confirmation doesn't match password.",
|
||||
"minPasswordLength": "Password must be 8 characters or more.",
|
||||
"passwordResetPage": "Reset Password",
|
||||
"passwordReset": "If we have your email on file, instructions for setting a new password have been sent to your email.",
|
||||
"passwordReset": "If we have your email or username on file, instructions for setting a new password have been sent to your email.",
|
||||
"invalidLoginCredentialsLong": "Uh-oh - your email address / username or password is incorrect.\n- Make sure they are typed correctly. Your username and password are case-sensitive.\n- You may have signed up with Facebook or Google-sign-in, not email so double-check by trying them.\n- If you forgot your password, click \"Forgot Password\".",
|
||||
"invalidCredentials": "There is no account that uses those credentials.",
|
||||
"accountSuspended": "This account, User ID \"<%= userId %>\", has been blocked for breaking the Community Guidelines (https://habitica.com/static/community-guidelines) or Terms of Service (https://habitica.com/static/terms). For details or to ask to be unblocked, please email our Community Manager at <%= communityManagerEmail %> or ask your parent or guardian to email them. Please include your @Username in the email.",
|
||||
@@ -143,7 +143,8 @@
|
||||
"confirmPassword": "Confirm Password",
|
||||
"usernameLimitations": "Username must be 1 to 20 characters, containing only letters a to z, numbers 0 to 9, hyphens, or underscores, and cannot include any inappropriate terms.",
|
||||
"usernamePlaceholder": "e.g., HabitRabbit",
|
||||
"emailPlaceholder": "e.g., rabbit@example.com",
|
||||
"emailPlaceholder": "e.g., gryphon@example.com",
|
||||
"emailUsernamePlaceholder": "e.g., habitrabbit or gryphon@example.com",
|
||||
"passwordPlaceholder": "e.g., ******************",
|
||||
"confirmPasswordPlaceholder": "Make sure it's the same password!",
|
||||
"joinHabitica": "Join Habitica",
|
||||
|
||||
@@ -134,6 +134,7 @@
|
||||
"saveCustomDayStart": "Save Custom Day Start",
|
||||
"registration": "Registration",
|
||||
"addLocalAuth": "Add Email and Password Login",
|
||||
"addPasswordAuth": "Add Password",
|
||||
"generateCodes": "Generate Codes",
|
||||
"generate": "Generate",
|
||||
"getCodes": "Get Codes",
|
||||
|
||||
@@ -341,7 +341,15 @@ api.resetPassword = {
|
||||
if (validationErrors) throw validationErrors;
|
||||
|
||||
const email = req.body.email.toLowerCase();
|
||||
const user = await User.findOne({ 'auth.local.email': email }).exec();
|
||||
const user = await User.findOne({
|
||||
$or: [
|
||||
{ 'auth.local.username': email.replace(/^@/, '') },
|
||||
{ 'auth.local.email': email },
|
||||
{ 'auth.apple.emails.value': email },
|
||||
{ 'auth.google.emails.value': email },
|
||||
{ 'auth.facebook.emails.value': email },
|
||||
],
|
||||
}).exec();
|
||||
|
||||
if (user) {
|
||||
// create an encrypted link to be used to reset the password
|
||||
@@ -385,7 +393,9 @@ api.updateEmail = {
|
||||
if (!user.auth.local.email) throw new BadRequest(res.t('userHasNoLocalRegistration'));
|
||||
|
||||
req.checkBody('newEmail', res.t('newEmailRequired')).notEmpty().isEmail();
|
||||
if (user.auth.local.hashed_password) {
|
||||
req.checkBody('password', res.t('missingPassword')).notEmpty();
|
||||
}
|
||||
const validationErrors = req.validationErrors();
|
||||
if (validationErrors) throw validationErrors;
|
||||
|
||||
@@ -395,6 +405,7 @@ api.updateEmail = {
|
||||
|
||||
if (emailAlreadyInUse) throw new NotAuthorized(res.t('cannotFulfillReq', { techAssistanceEmail: TECH_ASSISTANCE_EMAIL }));
|
||||
|
||||
if (user.auth.local.hashed_password) {
|
||||
const { password } = req.body;
|
||||
const isValidPassword = await passwordUtils.compare(user, password);
|
||||
if (!isValidPassword) throw new NotAuthorized(res.t('wrongPassword'));
|
||||
@@ -403,6 +414,7 @@ api.updateEmail = {
|
||||
if (user.auth.local.passwordHashMethod === 'sha1') {
|
||||
await passwordUtils.convertToBcrypt(user, password);
|
||||
}
|
||||
}
|
||||
|
||||
user.auth.local.email = req.body.newEmail.toLowerCase();
|
||||
await user.save();
|
||||
|
||||
@@ -128,12 +128,13 @@ async function registerLocal (req, res, { isV3 = false }) {
|
||||
}, { 'auth.local': 1 }).exec();
|
||||
|
||||
if (user) {
|
||||
if (email === user.auth.local.email) throw new NotAuthorized(res.t('emailTaken'));
|
||||
// Check that the lowercase username isn't already used
|
||||
if (existingUser) {
|
||||
if (email === user.auth.local.email && existingUser._id !== user._id) throw new NotAuthorized(res.t('emailTaken'));
|
||||
if (lowerCaseUsername === user.auth.local.lowerCaseUsername && existingUser._id !== user._id) throw new NotAuthorized(res.t('usernameTaken'));
|
||||
} else if (lowerCaseUsername === user.auth.local.lowerCaseUsername) {
|
||||
throw new NotAuthorized(res.t('usernameTaken'));
|
||||
} else {
|
||||
throw new NotAuthorized(res.t('emailTaken'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,8 +88,8 @@ export async function validatePasswordResetCodeAndFindUser (code) {
|
||||
if (isCodeValid) {
|
||||
user = await User.findById(userId).exec();
|
||||
|
||||
// check if user is found and if it's an email & password account
|
||||
if (!user || !user.auth || !user.auth.local || !user.auth.local.email) {
|
||||
// check if user is found
|
||||
if (!user) {
|
||||
isCodeValid = false;
|
||||
} else if (code !== user.auth.local.passwordResetCode) {
|
||||
// Make sure only the last code can be used
|
||||
|
||||
@@ -38,6 +38,12 @@ schema.plugin(baseModel, {
|
||||
plainObj.flags.newStuff = originalDoc.checkNewStuff();
|
||||
}
|
||||
|
||||
if (plainObj.auth && plainObj.auth.local && originalDoc.auth.local.hashed_password) {
|
||||
plainObj.auth.local.has_password = true;
|
||||
} else if (plainObj.auth && plainObj.auth.local && originalDoc.auth.local.email) {
|
||||
plainObj.auth.local.has_password = false;
|
||||
}
|
||||
|
||||
return plainObj;
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user