流星:从React Client调用verifyEmail?

问题描述 投票:0回答:1

[我已经阅读了很多关于using Accounts.onEmailVerificationLinkAccounts.verifyEmail的SO帖子,但是我还没有找到似乎可以解释如何从React客户端调用它们的帖子。

我已经设置了React Router,以将电子邮件验证链接上的点击路由到名为ConfirmEmail的React组件。路由器将验证令牌捕获到props.match.params.emailValidationToken

ConfirmEmail组件看起来像这样:

import React, {useEffect, useRef, useState} from "react";

function ConfirmEmail(props) {
    const {client, match, history} = props;

    const doSetUp = useRef(true);
    const emailVerificationToken = useRef(props.match.params.emailValidationToken);

    if (doSetUp.current){
        doSetUp.current = false;
        debugger;
        Accounts.onEmailVerificationLink(function(token, done) {
            Accounts.verifyEmail(emailVerificationToken.current, function(error) {
                debugger;
                if (error) {
                    console.log(error)
                } else {
                    console.log(success)
                }
            })
        });
    }


    return (
        <p>Your email address has been verified.</p>
    )
}

export default ConfirmEmail;

我已经尝试了几种不同的方法,但是还没有找到一种可行的方法。

处理来自React客户端的Meteor电子邮件验证链接的正确方法是什么?

reactjs meteor meteor-accounts
1个回答
0
投票

好吧,我不使用React Hooks,但是我想您会发现很容易将其移植到您的口味中。

所有这些都需要在componentDidMount()中发生。这样可以确保您使用令牌,并且只运行一次此过程。在以下代码中,toastr是客户端的UI通知系统。


import React, { Component } from 'react'
import { connect } from 'react-redux' // if you use redux, here it is used to get the user slug from props.
import { Link } from 'react-router-dom'
import PropTypes from 'prop-types' // not relevant
import { Accounts } from 'meteor/accounts-base'
import { toastr } from 'react-redux-toastr' // not relevant
import { TiWarningOutline, TiThumbsOk } from '../../components/shared/Icons/icons' // not relevant

class ConfirmEmail extends Component {
  constructor (props) {
    super(props)
    this.state = {
      linkExpired: false,
      logged: true // I need to know if the user is logged in before I test the token
    }
  }

  componentDidMount () {
    const { match, history, slug } = this.props
    const token = match.params.token

    // If the user is not logged in I cannot test the token against an email.
    if (!slug) {
      this.setState({ logged: false })
      return
    }

    Accounts.verifyEmail(token, err => {
      if (err && err.reason === 'Verify email link expired') {
        this.setState({ linkExpired: true })
      }
      // Inform the user what went wrong
      if (err) {
        toastr.light('Could not verify email!', `Error: ${err.reason}`, { timeOut: 2000, icon: (<TiWarningOutline style={{ fontSize: 42, color: 'red' }} />) })
      } else {
        // Confirm to user and move on to where you want to direct the user first or ask the user to close the window...or else
        toastr.light('You\'ve Successfully Confirmed Your Email Address!', { timeOut: 4000, icon: (<TiThumbsOk style={{ fontSize: 42, color: 'rgb(74, 181, 137)' }} />) })
        history.push('/feeds')
      }
    })
  }

  render () {
    const { linkExpired, logged } = this.state
    return (
      <div style={{ textAlign: 'center', paddingTop: 80 }}>
        {logged
          ? <>
            {linkExpired
              ? <p>This link has expired.</p>
              : <>
                <img src={`${IMAGE_BANK}/images/6.svg`} style={{ width: 36 }} /> // this is a spinner
                <p>Awaiting confirmation ...</p>
              </>}
          </>
          : <>
            <p style={{ maxWidth: 360, margin: '0 auto' }}>
              In order to verify your email address you need to be authenticated. Please sign in and try the verification link from your email one more time.
            </p>
            <br />
            <Link to='/signin' className='btn btn-primary'>Sign In</Link>
          </>
        }
      </div>
    )
  }
}

// this block is relevant in Redux context. Just gets the slug (or some other way to check if the user is logged in.)
const mapStateToProps = state => {
  const currentUser = state.user.currentUser
  return {
    slug: currentUser?.slug
  }
}
export default connect(mapStateToProps, { })(ConfirmEmail)

// from here, not so relevant
ConfirmEmail.propTypes = {
  params: PropTypes.object
}


© www.soinside.com 2019 - 2024. All rights reserved.