createVerifyEmailToken method

  1. @override
Future<String> createVerifyEmailToken(
  1. String email, {
  2. required Duration? allowNewJwtAfter,
  3. required Duration? verifyLinkExpiresAfter,
})
override

Implementation

@override
Future<String> createVerifyEmailToken(
  String email, {
  required Duration? allowNewJwtAfter,
  required Duration? verifyLinkExpiresAfter,
}) async {
  var collection =
      dbService.mongoDbController.collection(app.authSettings.collectionName);
  //? get the saved email verification and check if it exceeded the amount of a new verification
  var authModel =
      await collection.findOne(where.eq(ModelFields.email, email));
  // var authModel = await collection.doc(userId).getData();
  if (authModel == null) {
    throw FailedToStartVerificationException('no user found');
  }

  if (allowNewJwtAfter != null) {
    //! check if the user is already verified
    bool? verified = authModel[DbFields.verified];
    if (verified == true) {
      throw UserIsAlreadyVerifiedException();
    }
    var savedJwt = authModel[DbFields.verificationJWT];
    if (savedJwt != null) {
      // here check that the saved jwt is old enough to exceed the allowable amount of time
      var jwt = JWT.tryVerify(savedJwt, app.authSettings.jwtSecretKey);
      if (jwt != null) {
        DateTime createdAt =
            DateTime.fromMillisecondsSinceEpoch(jwt.payload['iat'] * 1000);
        DateTime now = DateTime.now();
        Duration diff = now.difference(createdAt);
        if (diff.inMicroseconds < allowNewJwtAfter.inMicroseconds) {
          // here the user is asking for a new token before the time has ended
          throw EarlyVerificationAskingException(
              (allowNewJwtAfter.inSeconds - diff.inSeconds));
        }
      }
    }
  }
  //? check if the user isn't already verified
  //? if exceed or no jwt saved just create the new one
  // here just get the auth model for the user to make sure that the user exists
  String userId = authModel[ModelFields.id];

  var payload = {
    ModelFields.id: userId,
    ModelFields.email: authModel[ModelFields.email],
  };
  var jwt = JWT(payload);
  String jwtString = jwt.sign(
    app.authSettings.jwtSecretKey,
    algorithm: app.authSettings.jwtAlgorithm,
    expiresIn: verifyLinkExpiresAfter,
  );
  //! just save it to the db auth model before returning
  var res = await collection
      .doc(userId)
      .update({DbFields.verificationJWT: jwtString});
  if (res.failure) {
    throw FailedToStartVerificationException('unknown db write failure');
  }

  return jwtString;
}