Save my secrets!

JavaScript (ES6),  60  50 bytes

Saved 10 bytes thanks to @JonasWilms!

Takes input as either (alias,password,secret) or (alias,password). Returns undefined the first time a secret is stored, or false if the password is incorrect.

f=(a,p,s,[P,v]=f[a]||[p])=>p==P&&(f[a]=[P,s||v],v)

Try a 1st test case online!

Try a 2nd test case online!

How?

We define a named function \$f\$ whose underlying object is also used to store the passwords and the secrets.

Commented

f = (             // f = named function whose underlying object is used for storage
  a,              // a = alias
  p,              // p = password
  s,              // s = optional secret
  [P, v] = f[a]   // if f[a] is defined, retrieve the password P and the secret v
           || [p] // otherwise, copy p in P
) =>              //
  p == P && (     // if p is not equal to P, yield false; else:
    f[a] = [      //   update f[a]:
      P,          //     save the new password (or leave it unchanged)
      s || v      //     save the new secret if it's defined, or keep the previous one
    ],            //
    v             //   return the previous secret
  )               //

Python 2, 94 93 bytes

def f(a,p,s=0,d={}):
 q,t=d.get(a,(0,0))
 if q==p:d[a]=p,s or t;return t
 elif q<1<s:d[a]=p,s

Try it online!

For once, Python's weird default dict parameter works in my favor...


Ruby, 64 bytes

Builds a hash for aliases to a single key-pair of password => secret. Probably could be more elegant.

->a,w,s=p{@q||={};(b=@q[a])?s&&b[w]?b[w]=s:b[w]:s&&@q[a]={w=>s}}

Try it online!