I have searched for days, but I can't get my answer, so I create this post.
I developed a web app, so the user can create event in their Google Calendar. It is working. But, I can't figure, why this app only asks the user credential once.
For example:
User John access the .aspx page then he redirected to Google Authorized page because it's the first time John access the page.
After Authorized, John can create an event in his Google Calendar.
It works until this step. The problem occurred when John logout from his google account.
If Dave accesses this page from another computer, he's not redirected to Google Authorized page and suddenly directly creates an event in
JOHN's Calendar.
Can someone help me, why this problem occurred?
this is my code:
Protected Sub new_authentication()
Dim datafolder As String = Server.MapPath("App_Data/CalendarService.api.auth.store")
Dim scopes As IList(Of String) = New List(Of String)()
Dim UserId As String = "GoogleID_co"
scopes.Add(CalendarService.Scope.Calendar)
Dim myclientsecret As New ClientSecrets() With { _
.ClientId = myClientID, _
.ClientSecret = ClientSecret _
}
Dim flow As GoogleAuthorizationCodeFlow
flow = New GoogleAuthorizationCodeFlow(New GoogleAuthorizationCodeFlow.Initializer() With { _
.DataStore = New FileDataStore(datafolder), _
.ClientSecrets = myclientsecret, _
.Scopes = scopes _
})
Dim uri As String = Request.Url.ToString()
Dim code = Request("code")
If code IsNot Nothing Then
Dim token = flow.ExchangeCodeForTokenAsync(UserId, code, uri.Substring(0, uri.IndexOf("?")), CancellationToken.None).Result
' Extract the right state.
Dim oauthState = AuthWebUtility.ExtracRedirectFromState(flow.DataStore, UserId, Request("state")).Result
Response.Redirect(oauthState)
Else
Dim result = New AuthorizationCodeWebApp(flow, uri, uri).AuthorizeAsync(UserId, CancellationToken.None).Result
If result.RedirectUri IsNot Nothing Then
' Redirect the user to the authorization server.
Response.Redirect(result.RedirectUri)
Else
' The data store contains the user credential, so the user has been already authenticated.
myCalendarservice = New CalendarService(New BaseClientService.Initializer() With { _
.ApplicationName = "My Calendar", _
.HttpClientInitializer = result.Credential _
})
createcalendar()
End If
End If
End Sub
This is my createcalendar sub
Protected Sub createcalendar()
Dim newEvent As New [Event]() With { _
.Summary = "Google I/O 2015", _
.Location = "800 Howard St., San Francisco, CA 94103", _
.Description = "A chance to hear more about Google's developer products.", _
.Start = New EventDateTime() With { _
.DateTime = DateTime.Parse("2015-07-13T09:00:00-07:00"), _
.TimeZone = "America/Los_Angeles" _
}, _
.[End] = New EventDateTime() With { _
.DateTime = DateTime.Parse("2015-07-14T17:00:00-07:00"), _
.TimeZone = "America/Los_Angeles" _
}, _
.Recurrence = New [String]() {"RRULE:FREQ=DAILY;COUNT=2"}, _
.Attendees = New EventAttendee() {New EventAttendee() With { _
.Email = "lpage#example.com" _
}, New EventAttendee() With { _
.Email = "sbrin#example.com" _
}}, _
.Reminders = New [Event].RemindersData() With { _
.UseDefault = False, _
.[Overrides] = New EventReminder() {New EventReminder() With { _
.Method = "email", _
.Minutes = 24 * 60 _
}, New EventReminder() With { _
.Method = "sms", _
.Minutes = 10 _
}} _
} _
}
Dim calendarId As [String] = "primary"
Dim request As EventsResource.InsertRequest = myCalendarservice.Events.Insert(newEvent, calendarId)
Dim createdEvent As [Event] = request.Execute()
End Sub
I resolved my problem. I found that the name of token always same that's why this problem occurred. So, just replace this code:
Dim datafolder As String = Server.MapPath("App_Data/CalendarService.api.auth.store")
Dim scopes As IList(Of String) = New List(Of String)()
Dim UserId As String = "GoogleID_co"
into
Dim datafolder As String = Server.MapPath("App_Data/CalendarService.api.auth.store")
Dim scopes As IList(Of String) = New List(Of String)()
Dim UserId As String = "GoogleID_co" & {unique Identifier such as userid,username,etc}
Related
I use Facebook login for website currently it doesn't retrieves email address I have update to Facebook Graph API endpoint version from v9.0 to v11.0 also I requested for both email and public_profile permissions in App Review section like below image but it still retrieve just (id,name,first_name,last_name ) and email is empty here is the VB.NET code to handle the Facebook Graph API
Public Sub GetUserData(ByVal FacebookAppId As String, ByVal FacebookAppSecret As String, ByVal RedirectURL As String, ByVal Code As String)
Dim targetUri As Uri = New Uri("https://graph.facebook.com/v11.0/oauth/access_token?client_id=" & FacebookAppId & "&client_secret=" & FacebookAppSecret & "&redirect_uri=" & RedirectURL & "&code=" & Code)
Dim at As HttpWebRequest = CType(HttpWebRequest.Create(targetUri), HttpWebRequest)
Dim str As System.IO.StreamReader = New System.IO.StreamReader(at.GetResponse().GetResponseStream())
Dim token As String = str.ReadToEnd().ToString().Replace("access_token=", "")
Dim combined As String() = token.Split(""""c)
Dim accessToken As String = combined(3)
Dim url As String = "https://graph.facebook.com/v11.0/me?fields=id%2Cname%2Cemail%2Cfirst_name%2Clast_name&access_token=" & accessToken.Trim(""""c) & ""
Dim request As WebRequest = WebRequest.Create(url)
request.ContentType = "application/json"
request.Method = "GET"
Dim userInfo As StreamReader = New StreamReader(request.GetResponse().GetResponseStream())
Dim jsonResponse As String = String.Empty
jsonResponse = userInfo.ReadToEnd()
Dim sr As JavaScriptSerializer = New JavaScriptSerializer()
Dim jsondata As String = jsonResponse
Dim converted As FacebookUserData = sr.Deserialize(Of FacebookUserData)(jsondata)
userId = converted.id
userName = converted.name
userFirstName = converted.first_name
userLastName = converted.last_name
userEmail = converted.email
End Sub
Permissions and Features image
Here is the login button
Protected Sub btnFBSignIn_Click(sender As Object, e As EventArgs) Handles btnFBSignIn.Click
Dim fbAppId As String = "AppID"
Dim fbUrllRedirect = "https://mywebsite.com/Login"
Dim fbApiUrl As String = "https://www.facebook.com/v11.0/dialog/oauth/?client_id=" & fbAppId & "&redirect_uri=" & fbUrllRedirect & "&response_type=code&state=1"
Response.Redirect(fbApiUrl)
End Sub
I am trying to set up some password policies, I managed to successfully do this in C#, but I need to convert the code into VB. There are two issues that I cannot figure out:
1) app.UseUserManagerFactory does not exist;
It states UseUserManagerFactory is not a member of Owin.IAppBuilder
2) The OnCreate attribute when instantiating the Provider is not being passed correctly
Public Sub ConfigureAuth(app As IAppBuilder)
'Configure the UserManager
app.UseUserManagerFactory(New IdentityFactoryOptions(Of ApplicationUserManager)() With { _
.DataProtectionProvider = app.GetDataProtectionProvider(), _
.Provider = New IdentityFactoryProvider(Of ApplicationUserManager)() With { _
.OnCreate = ApplicationUserManager.Create _
} _
})
Here is the Create function for the sake of completeness:
Public Shared Function Create(options As IdentityFactoryOptions(Of ApplicationUserManager))
Dim manager = New ApplicationUserManager(New ApplicationUserStore(New ApplicationDbContext()))
manager.UserValidator = New UserValidator(Of ApplicationUser)(manager) With {.AllowOnlyAlphanumericUserNames = False, .RequireUniqueEmail = True}
manager.PasswordValidator = New PasswordValidator()
Dim dataProtectionProvider = options.DataProtectionProvider
If (dataProtectionProvider IsNot Nothing) Then
' Do stuff
End If
Return manager
End Function
Any help would be appreciated, my VB skills coupled with the lack of documentation has me scratching my head.
i'm traying to display a list of competitions contained in my data base , but it strikes me each time this error:
A circular reference was detected while serializing an object of type 'WhereSelectListIterator2[jTableSampleDatabaseLayer.Hik.JTable.Models.Concour,VB$AnonymousType_28[System.String,System.Nullable1[System.Int32],System.Nullable1[System.Int32],System.DateTime,System.Int32,System.Int32,System.String,System.Int32]]' on type 'System.Collections.Generic.IEnumerable1[jTableSampleDatabaseLayer.Hik.JTable.Models.Concour]``'.
here is my code in vb :
Dim x As jTableSampleDatabaseLayer.totofootEntities = _
New jTableSampleDatabaseLayer.totofootEntities
Dim dataSource = New MemoryDataSource()
Dim liste As List(Of Concour) = x.Concours.ToList()
dataSource.Concours.AddRange(liste)
''ajout
Try
Dim concours = dataSource.Concours
Return Json(New With { _
Key .Result = "OK", _
Key .Records = concours _
}, JsonRequestBehavior.AllowGet)
Catch ex As Exception
Return Json(New With { _
Key .Result = "ERROR", _
Key .Message = ex.Message _
}, JsonRequestBehavior.AllowGet)
End Try
How can I avoid this error ?
I've tried to change the code in order to avoid this error
now i don't get anymore the error but i'm getting the result with all the attribute are equal to null and the same number of registration in my DB
{"Result":"OK","Records":[{"numero_concours":null,"numero_etape":0,"numero_type":null,"numero_nature":null,"titre_concours":null,"date_de_sortie":"/Date(-62135596800000)/","nbre_matchs":0,"nbre_rangs":0,"Etape":null,"Nature":null,"Type":null,"Primes":[],"Rangs":[],"Recettes":[],"Rencontres":[]},{"numero_concours":null,"numero_etape":0,"numero_type":null,"numero_nature":null,"titre_concours":null,"date_de_sortie":"/Date(-62135596800000)/","nbre_matchs":0,"nbre_rangs":0,"Etape":null,"Nature":null,"Type":null,"Primes":[],"Rangs":[],"Recettes":[],"Rencontres":[]}]}``'.
the new code :
Dim x As jTableSampleDatabaseLayer.totofootEntities = New jTableSampleDatabaseLayer.totofootEntities
Dim dataSource = New MemoryDataSource()
Dim liste As List(Of Concour) = x.Concours.ToList()
dataSource.Concours.AddRange(liste.Select(Function(p) New Concour))
''ajout
Try
Dim concours = dataSource.Concours
Return Json(New With {Key .Result = "OK", Key .Records = concours}, JsonRequestBehavior.AllowGet)
Catch ex As Exception
Return Json(New With {Key .Result = "ERROR", Key .Message = ex.Message}, JsonRequestBehavior.AllowGet)
End Try
I am trying to use one of the best example for checking the username availability from the below site
http://www.highoncoding.com/Articles/439_Performing_Instant_UserName_Availability_Check_Using_JQuery_Ajax_API.aspx
And It's just verifying with some pre-initiated names but I wan't to try with my database can anyone suggest me how to proceed further.
Here is the code:
<script language="javascript" type="text/javascript">
var userName = '';
$(document).ready(function()
{
$("#txtUserName").blur(function()
{
userName = $(this).val();
if(userName.length <= 6)
{
$("#display").text("username must be atleast 7 characters");
$("#display").css("background-color","red");
}
else
{
$.ajax(
{
type:"POST",
url:"AjaxService.asmx/CheckUserNameAvailability",
data:"{\"userName\":\"" + userName + "\"}",
dataType:"json",
contentType:"application/json",
success: function(response)
{
if(response.d == true)
{
$("#display").text("username is available");
$("#display").css("background-color","lightgreen");
}
else
{
$("#display").text("username is already taken");
$("#display").css("background-color","red");
}
}
});
}
});
});
</script>
This AjaxService.asmx:
Imports System.Collections
Imports System.ComponentModel
Imports System.Data
Imports System.Linq
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Xml.Linq
Imports System.Collections.Generic
Namespace JQueryUserNameAvailability
<WebService([Namespace] := "http://tempuri.org/")> _
<WebServiceBinding(ConformsTo := WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
<System.Web.Script.Services.ScriptService> _
Public Class AjaxService
Inherits System.Web.Services.WebService
<WebMethod> _
Public Function CheckUserNameAvailability(userName As String) As Boolean
Dim userNames As List(Of [String]) = New List(Of String)() From { _
"azamsharp", _
"johndoe", _
"marykate", _
"alexlowe", _
"scottgu" _
}
Dim user = (From u In userNames Where u.ToLower().Equals(userName.ToLower())u).SingleOrDefault(Of [String])()
Return If([String].IsNullOrEmpty(user), True, False)
End Function
End Class
End Namespace
Modified code:
Public Function CheckUserNameAvailability(ByVal userName As String) As Boolean
Dim strSql As String = String.Format("SELECT COUNT(UserNameCol) FROM Registration WHERE UserNameCol = '{0}'", userName)
Dim strConnection As String = "Data Source=.\sqlexpress;Initial Catalog=Users;Integrated Security=True"
Dim sqlConn As New SqlConnection(strConnection)
Dim sqlDataAdap As New SqlDataAdapter(strSql, sqlConn)
Dim dt As New DataTable()
sqlDataAdap.Fill(dt)
If Convert.ToInt32(dt.Rows(0)(0)) > 0 Then
Return False
End If
Return True
End Function
Modify your CheckUserNameAvailability function to get data from the table where you have saved all the username. An example:
Public Function CheckUserNameAvailability(userName As String) As Boolean
Dim strSql as String = String.Format("SELECT COUNT(userNameCol) FROM users WHERE userNameCol = '{0}'", userName)
Dim sqlConn as new SqlConnection(SQL Connection String)
Dim sqlDataAdap as new SqlDataAdapter(strSql, sqlConn)
Dim dt as new DataTable()
sqlDataAdap.Fill(dt)
If Convert.ToInt32(dt.Rows(0)(0)) > 0 Then
Return false
End If
Return true
End Function
I am trying to write some code to check the AD password age during a user login and notify them of the 15 remaining days. I am using the ASP.Net code that I found on the Microsoft MSDN site and I managed to add a function that checks the if the account is set to change password at next login. The login and the change password at next login works great but I am having some problems with the check for the password age.
This is the VB.Net code for the DLL file:
Imports System
Imports System.Text
Imports System.Collections
Imports System.DirectoryServices
Imports System.DirectoryServices.AccountManagement
Imports System.Reflection 'Needed by the Password Expiration Class Only -Vince
Namespace FormsAuth
Public Class LdapAuthentication
Dim _path As String
Dim _filterAttribute As String
'Code added for the password expiration added by Vince
Private _domain As DirectoryEntry
Private _passwordAge As TimeSpan = TimeSpan.MinValue
Const UF_DONT_EXPIRE_PASSWD As Integer = &H10000
'Function added by Vince
Public Sub New()
Dim root As New DirectoryEntry("LDAP://rootDSE")
root.AuthenticationType = AuthenticationTypes.Secure
_domain = New DirectoryEntry("LDAP://" & root.Properties("defaultNamingContext")(0).ToString())
_domain.AuthenticationType = AuthenticationTypes.Secure
End Sub
'Function added by Vince
Public ReadOnly Property PasswordAge() As TimeSpan
Get
If _passwordAge = TimeSpan.MinValue Then
Dim ldate As Long = LongFromLargeInteger(_domain.Properties("maxPwdAge")(0))
_passwordAge = TimeSpan.FromTicks(ldate)
End If
Return _passwordAge
End Get
End Property
Public Sub New(ByVal path As String)
_path = path
End Sub
'Function added by Vince
Public Function DoesUserHaveToChangePassword(ByVal userName As String) As Boolean
Dim ctx As PrincipalContext = New PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain)
Dim up = UserPrincipal.FindByIdentity(ctx, userName)
Return (Not up.LastPasswordSet.HasValue)
'returns true if last password set has no value.
End Function
Public Function IsAuthenticated(ByVal domain As String, ByVal username As String, ByVal pwd As String) As Boolean
Dim domainAndUsername As String = domain & "\" & username
Dim entry As DirectoryEntry = New DirectoryEntry(_path, domainAndUsername, pwd)
Try
'Bind to the native AdsObject to force authentication.
Dim obj As Object = entry.NativeObject
Dim search As DirectorySearcher = New DirectorySearcher(entry)
search.Filter = "(SAMAccountName=" & username & ")"
search.PropertiesToLoad.Add("cn")
Dim result As SearchResult = search.FindOne()
If (result Is Nothing) Then
Return False
End If
'Update the new path to the user in the directory.
_path = result.Path
_filterAttribute = CType(result.Properties("cn")(0), String)
Catch ex As Exception
Throw New Exception("Error authenticating user. " & ex.Message)
End Try
Return True
End Function
Public Function GetGroups() As String
Dim search As DirectorySearcher = New DirectorySearcher(_path)
search.Filter = "(cn=" & _filterAttribute & ")"
search.PropertiesToLoad.Add("memberOf")
Dim groupNames As StringBuilder = New StringBuilder()
Try
Dim result As SearchResult = search.FindOne()
Dim propertyCount As Integer = result.Properties("memberOf").Count
Dim dn As String
Dim equalsIndex, commaIndex
Dim propertyCounter As Integer
For propertyCounter = 0 To propertyCount - 1
dn = CType(result.Properties("memberOf")(propertyCounter), String)
equalsIndex = dn.IndexOf("=", 1)
commaIndex = dn.IndexOf(",", 1)
If (equalsIndex = -1) Then
Return Nothing
End If
groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1))
groupNames.Append("|")
Next
Catch ex As Exception
Throw New Exception("Error obtaining group names. " & ex.Message)
End Try
Return groupNames.ToString()
End Function
'Function added by Vince
Public Function WhenExpires(ByVal username As String) As TimeSpan
Dim ds As New DirectorySearcher(_domain)
ds.Filter = [String].Format("(&(objectClass=user)(objectCategory=person)(sAMAccountName={0}))", username)
Dim sr As SearchResult = FindOne(ds)
Dim user As DirectoryEntry = sr.GetDirectoryEntry()
Dim flags As Integer = CInt(user.Properties("userAccountControl").Value)
If Convert.ToBoolean(flags And UF_DONT_EXPIRE_PASSWD) Then
'password never expires
Return TimeSpan.MaxValue
End If
'get when they last set their password
Dim pwdLastSet As DateTime = DateTime.FromFileTime(LongFromLargeInteger(user.Properties("pwdLastSet").Value))
' return pwdLastSet.Add(PasswordAge).Subtract(DateTime.Now);
If pwdLastSet.Subtract(PasswordAge).CompareTo(DateTime.Now) > 0 Then
Return pwdLastSet.Subtract(PasswordAge).Subtract(DateTime.Now)
Else
Return TimeSpan.MinValue
'already expired
End If
End Function
'Function added by Vince
Private Function LongFromLargeInteger(ByVal largeInteger As Object) As Long
Dim type As System.Type = largeInteger.[GetType]()
Dim highPart As Integer = CInt(type.InvokeMember("HighPart", BindingFlags.GetProperty, Nothing, largeInteger, Nothing))
Dim lowPart As Integer = CInt(type.InvokeMember("LowPart", BindingFlags.GetProperty, Nothing, largeInteger, Nothing))
Return CLng(highPart) << 32 Or CUInt(lowPart)
End Function
'Function added by Vince
Private Function FindOne(ByVal searcher As DirectorySearcher) As SearchResult
Dim sr As SearchResult = Nothing
Dim src As SearchResultCollection = searcher.FindAll()
If src.Count > 0 Then
sr = src(0)
End If
src.Dispose()
Return sr
End Function
End Class
End Namespace
And this is the Login.aspx page:
sub Login_Click(sender as object,e as EventArgs)
Dim adPath As String = "LDAP://DC=xxx,DC=com" 'Path to your LDAP directory server
Dim adAuth As LdapAuthentication = New LdapAuthentication(adPath)
Try
If (True = adAuth.DoesUserHaveToChangePassword(txtUsername.Text)) Then
Response.Redirect("passchange.htm")
ElseIf (True = adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text)) Then
Dim groups As String = adAuth.GetGroups()
'Create the ticket, and add the groups.
Dim isCookiePersistent As Boolean = chkPersist.Checked
Dim authTicket As FormsAuthenticationTicket = New FormsAuthenticationTicket(1, _
txtUsername.Text, DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups)
'Encrypt the ticket.
Dim encryptedTicket As String = FormsAuthentication.Encrypt(authTicket)
'Create a cookie, and then add the encrypted ticket to the cookie as data.
Dim authCookie As HttpCookie = New HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
If (isCookiePersistent = True) Then
authCookie.Expires = authTicket.Expiration
End If
'Add the cookie to the outgoing cookies collection.
Response.Cookies.Add(authCookie)
'Retrieve the password life
Dim t As TimeSpan = adAuth.WhenExpires(txtUsername.Text)
'You can redirect now.
If (passAge.Days = 90) Then
errorLabel.Text = "Your password will expire in " & DateTime.Now.Subtract(t)
'errorLabel.Text = "This is"
'System.Threading.Thread.Sleep(5000)
Response.Redirect("http://somepage.aspx")
Else
Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, False))
End If
Else
errorLabel.Text = "Authentication did not succeed. Check user name and password."
End If
Catch ex As Exception
errorLabel.Text = "Error authenticating. " & ex.Message
End Try
End Sub
`
Every time I have this Dim t As TimeSpan = adAuth.WhenExpires(txtUsername.Text) enabled, I receive "Arithmetic operation resulted in an overflow." during the login and won't continue.
What am I doing wrong? How can I correct this? Please help!!
Thank you very much for any help in advance.
Vince
Ok I tried to use a different approach.
Here are the functions converted from C#:
Public Function PassAboutToExpire(ByVal userName As String) As Integer
Dim passwordAge As TimeSpan
Dim currentDate As DateTime
Dim ctx As PrincipalContext = New PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain)
Dim up = UserPrincipal.FindByIdentity(ctx, userName)
'Return (Not up.LastPasswordSet.HasValue)
'returns true if last password set has no value.
Dim pwdLastSet As DateTime = DateTime.FromFileTime(LongFromLargeInteger(up.LastPasswordSet))
currentDate = Now
passwordAge = currentDate.Subtract(pwdLastSet)
If passwordAge.Days > 75 Then
'If pwdLastSet.Subtract(passwordAge).CompareTo(DateTime.Now) > 0 Then
'Dim value As TimeSpan = pwdLastSet.Subtract(passwordAge).Subtract(DateTime.Now)
'If (value.Days > 75) Then
Return passwordAge.Days
'End If
Else
Return False
'already expired
End If
End Function
Private Function LongFromLargeInteger(ByVal largeInteger As Object) As Long
Dim type As System.Type = largeInteger.[GetType]()
Dim highPart As Integer = CInt(type.InvokeMember("HighPart", BindingFlags.GetProperty, Nothing, largeInteger, Nothing))
Dim lowPart As Integer = CInt(type.InvokeMember("LowPart", BindingFlags.GetProperty, Nothing, largeInteger, Nothing))
Return CLng(highPart) << 32 Or CUInt(lowPart)
End Function
And here is the code snippet from the logon.aspx page:
sub Login_Click(sender as object,e as EventArgs)
Dim adPath As String = "LDAP://DC=xzone,DC=com" 'Path to your LDAP directory server
Dim adAuth As LdapAuthentication = New LdapAuthentication(adPath)
Try
If (True = adAuth.DoesUserHaveToChangePassword(txtUsername.Text)) Then
Response.Redirect("http://mypass.nsu.edu")
ElseIf (adAuth.PassAboutToExpire(txtUsername.Text) > 0) Then
Response.Redirect("http://www.yahoo.com")
Now when I try to login I receive the exception error: Error authenticating. Method 'System.DateTime.HighPart' not found.
and I don't know why. Anyone has any idea?
I would use the DateDiff function to determine the remaining number of days rather than using currentDate.Subtract
Dim passwordAge As Integer = (CInt)DateDiff(DateInterval.Day, Now, up.LastPasswordSet))
That will return an integer representing the number of days between now and when the password will need to be set.