account-security.js 2.4 KB

1234567891011121314151617181920212223242526272829303132
  1. function mayMigrateLegacyPassword(target) {
  2. return !!target && target.get('legacyPasswordMigrationAllowed') === true && target.get('passwordResetRequired') !== true && !target.get('isDisabled') && !target.get('isDeleted');
  3. }
  4. async function migrateLegacyLogin(username,password) {
  5. const original=await migratedLoginTarget(username);
  6. if(!mayMigrateLegacyPassword(original)) fail(401,'账号或密码错误;如首次登录旧账号,请联系管理员重置密码');
  7. const revision=Number(original.get('credentialRevision')||0);
  8. const verified=await verifyLegacyPassword(username,password),target=await migratedLoginTarget(username,verified);
  9. if(!target || target.id!==original.id || !mayMigrateLegacyPassword(target)) fail(401,'账号验证未通过');
  10. target.set('credentialExpectedRevision',revision);target.set('credentialMigrationAttempt',true);
  11. target.setPassword(password);await target.save(null,{useMasterKey:true});
  12. return Parse.User.logIn(String(target.get('username')),password);
  13. }
  14. async function changeAppPassword(input,current) {
  15. const oldPassword=String(input.currentPassword||''),password=String(input.newPassword||'');
  16. if(!oldPassword || password.length<8 || password.length>72)fail(400,'请输入当前密码及 8 至 72 位新密码');
  17. if(oldPassword===password)fail(400,'新密码不能与当前密码相同');
  18. const revision=Number(current.get('credentialRevision')||0);
  19. let verified;try{verified=await Parse.User.logIn(String(current.get('username')),oldPassword);}catch(error){if(Number(error.code)===101)fail(400,'当前密码不正确');throw error;}
  20. if(verified.id!==current.id)fail(403,'账号验证未通过');
  21. current.set('credentialExpectedRevision',revision);current.setPassword(password);current.set('passwordResetRequired',false);
  22. try{await current.save(null,{useMasterKey:true});await revokeUserSessions(current);}finally{
  23. // Reauthentication may have issued a temporary session even when saving failed.
  24. const q=new Parse.Query('_Session');q.equalTo('sessionToken',verified.getSessionToken());await Parse.Object.destroyAll(await q.find({useMasterKey:true}),{useMasterKey:true});
  25. }
  26. return {changed:true,loginRequired:true};
  27. }
  28. async function logoutAppSession(request,current) {
  29. const token=String(request.body?.token||'');
  30. if(token){const q=new Parse.Query('_Session');q.equalTo('user',current);q.equalTo('sessionToken',token);await Parse.Object.destroyAll(await q.find({useMasterKey:true}),{useMasterKey:true});}
  31. return {loggedOut:true};
  32. }