11import * as crypto from "crypto" ;
22import * as bcrypt from "bcryptjs" ;
33import * as jsonwebtoken from "jsonwebtoken" ;
4- import { Base } from "./base" ;
5- import { TokenUser } from "./TokenUser" ;
6- import { User } from "./User" ;
74import { Config } from "./Config" ;
8- import { Util } from "./Util" ;
9-
5+ import { NoderedUtil , TokenUser , WellknownIds , Rolemember , User } from "openflow-api" ;
106export class Crypt {
117 static encryption_key : string = Config . aes_secret . substr ( 0 , 32 ) ; // must be 256 bytes (32 characters)
128 static iv_length : number = 16 ; // for AES, this is always 16
139 static bcrypt_salt_rounds : number = 12 ;
14-
10+ static rootUser ( ) : User {
11+ var result : User = new User ( ) ;
12+ result . _type = "user" ; result . name = "root" ; result . username = "root" ; result . _id = WellknownIds . root ;
13+ result . roles = [ ] ; result . roles . push ( new Rolemember ( "admins" , WellknownIds . admins ) ) ;
14+ return result ;
15+ }
16+ static rootToken ( ) : string {
17+ return Crypt . createToken ( this . rootUser ( ) , Config . shorttoken_expires_in ) ;
18+ }
19+ public static async SetPassword ( user : User , password : string ) : Promise < void > {
20+ user . passwordhash = await Crypt . hash ( password ) ;
21+ if ( ! ( this . ValidatePassword ( user , password ) ) ) { throw new Error ( "Failed validating password after hasing" ) ; }
22+ }
23+ public static async ValidatePassword ( user : User , password : string ) : Promise < boolean > {
24+ return await Crypt . compare ( password , user . passwordhash ) ;
25+ }
1526 static encrypt ( text : string ) : string {
1627 let iv : Buffer = crypto . randomBytes ( Crypt . iv_length ) ;
1728 let cipher : crypto . Cipher = crypto . createCipheriv ( "aes-256-cbc" , Buffer . from ( Crypt . encryption_key ) , iv ) ;
1829 let encrypted : Buffer = cipher . update ( ( text as any ) ) ;
1930 encrypted = Buffer . concat ( [ encrypted , cipher . final ( ) ] ) ;
2031 return iv . toString ( "hex" ) + ":" + encrypted . toString ( "hex" ) ;
2132 }
22-
2333 static decrypt ( text : string ) : string {
2434 let textParts : string [ ] = text . split ( ":" ) ;
2535 let iv : Buffer = Buffer . from ( textParts . shift ( ) , "hex" ) ;
@@ -29,7 +39,6 @@ export class Crypt {
2939 decrypted = Buffer . concat ( [ decrypted , decipher . final ( ) ] ) ;
3040 return decrypted . toString ( ) ;
3141 }
32-
3342 static async hash ( password : string ) : Promise < string > {
3443 return new Promise < string > ( async ( resolve , reject ) => {
3544 try {
@@ -45,8 +54,8 @@ export class Crypt {
4554 static async compare ( password : string , passwordhash : string ) : Promise < boolean > {
4655 return new Promise < boolean > ( async ( resolve , reject ) => {
4756 try {
48- if ( Util . IsNullEmpty ( password ) ) { return reject ( "Password cannot be empty" ) ; }
49- if ( Util . IsNullEmpty ( passwordhash ) ) { return reject ( "Passwordhash cannot be empty" ) ; }
57+ if ( NoderedUtil . IsNullEmpty ( password ) ) { return reject ( "Password cannot be empty" ) ; }
58+ if ( NoderedUtil . IsNullEmpty ( passwordhash ) ) { return reject ( "Passwordhash cannot be empty" ) ; }
5059 bcrypt . compare ( password , passwordhash , async ( error , res ) => {
5160 if ( error ) { return reject ( error ) ; }
5261 resolve ( res ) ;
@@ -57,7 +66,14 @@ export class Crypt {
5766 } ) ;
5867 }
5968 static createToken ( item : User | TokenUser , expiresIn : string ) : string {
60- var user : TokenUser = new TokenUser ( item ) ;
69+ var user : TokenUser = new TokenUser ( ) ;
70+ user . _type = ( item as User ) . _type ;
71+ user . _id = item . _id ;
72+ user . impostor = ( item as TokenUser ) . impostor ;
73+ user . name = item . name ;
74+ user . username = item . username ;
75+ user . roles = item . roles ;
76+
6177 var token : string = jsonwebtoken . sign ( { data : user } , Crypt . encryption_key ,
6278 { expiresIn : expiresIn } ) ; // 60 (seconds), "2 days", "10h", "7d"
6379 return token ;
0 commit comments