@ -1,3 +1,5 @@
require " crypto/subtle "
def generate_token ( email , scopes , expire , key , db )
def generate_token ( email , scopes , expire , key , db )
session = " v1: #{ Base64 . urlsafe_encode ( Random :: Secure . random_bytes ( 32 ) ) } "
session = " v1: #{ Base64 . urlsafe_encode ( Random :: Secure . random_bytes ( 32 ) ) } "
PG_DB . exec ( " INSERT INTO session_ids VALUES ($1, $2, $3) " , session , email , Time . utc )
PG_DB . exec ( " INSERT INTO session_ids VALUES ($1, $2, $3) " , session , email , Time . utc )
@ -76,32 +78,31 @@ def validate_request(token, session, request, key, db, locale = nil)
raise translate ( locale , " Hidden field \" token \" is a required field " )
raise translate ( locale , " Hidden field \" token \" is a required field " )
end
end
if token [ " signature " ] != sign_token ( key , token )
expire = token [ " expire " ]? . try & . as_i
raise translate ( locale , " Invalid signature " )
if expire . try & . < Time . utc . to_unix
raise translate ( locale , " Token is expired, please try again " )
end
end
if token [ " session " ] != session
if token [ " session " ] != session
raise translate ( locale , " Erroneous token " )
raise translate ( locale , " Erroneous token " )
end
end
if token [ " nonce " ]? && ( nonce = db . query_one? ( " SELECT * FROM nonces WHERE nonce = $1 " , token [ " nonce " ] , as : { String , Time } ) )
if nonce [ 1 ] > Time . utc
db . exec ( " UPDATE nonces SET expire = $1 WHERE nonce = $2 " , Time . utc ( 1990 , 1 , 1 ) , nonce [ 0 ] )
else
raise translate ( locale , " Erroneous token " )
end
end
scopes = token [ " scopes " ] . as_a . map { | v | v . as_s }
scopes = token [ " scopes " ] . as_a . map { | v | v . as_s }
scope = " #{ request . method } : #{ request . path . lchop ( " /api/v1/auth/ " ) . lstrip ( " / " ) } "
scope = " #{ request . method } : #{ request . path . lchop ( " /api/v1/auth/ " ) . lstrip ( " / " ) } "
if ! scopes_include_scope ( scopes , scope )
if ! scopes_include_scope ( scopes , scope )
raise translate ( locale , " Invalid scope " )
raise translate ( locale , " Invalid scope " )
end
end
expire = token [ " expire " ]? . try & . as_i
if ! Crypto :: Subtle . constant_time_compare ( token [ " signature " ] . to_s , sign_token ( key , token ) )
if expire . try & . < Time . utc . to_unix
raise translate ( locale , " Invalid signature " )
raise translate ( locale , " Token is expired, please try again " )
end
if token [ " nonce " ]? && ( nonce = db . query_one? ( " SELECT * FROM nonces WHERE nonce = $1 " , token [ " nonce " ] , as : { String , Time } ) )
if nonce [ 1 ] > Time . utc
db . exec ( " UPDATE nonces SET expire = $1 WHERE nonce = $2 " , Time . utc ( 1990 , 1 , 1 ) , nonce [ 0 ] )
else
raise translate ( locale , " Erroneous token " )
end
end
end
return { scopes , expire , token [ " signature " ] . as_s }
return { scopes , expire , token [ " signature " ] . as_s }