1*fe5cfb17STomasz Sapeta // Copyright 2022-present 650 Industries. All rights reserved.
2*fe5cfb17STomasz Sapeta 
3*fe5cfb17STomasz Sapeta import Security
4*fe5cfb17STomasz Sapeta import ABI48_0_0ExpoModulesCore
5*fe5cfb17STomasz Sapeta 
6*fe5cfb17STomasz Sapeta public class RandomModule: Module {
definitionnull7*fe5cfb17STomasz Sapeta   public func definition() -> ModuleDefinition {
8*fe5cfb17STomasz Sapeta     Name("ExpoRandom")
9*fe5cfb17STomasz Sapeta 
10*fe5cfb17STomasz Sapeta     AsyncFunction("getRandomBase64StringAsync", getRandomBase64String)
11*fe5cfb17STomasz Sapeta 
12*fe5cfb17STomasz Sapeta     Function("getRandomBase64String", getRandomBase64String)
13*fe5cfb17STomasz Sapeta   }
14*fe5cfb17STomasz Sapeta }
15*fe5cfb17STomasz Sapeta 
getRandomBase64Stringnull16*fe5cfb17STomasz Sapeta private func getRandomBase64String(length: Int) throws -> String {
17*fe5cfb17STomasz Sapeta   var bytes = [UInt8](repeating: 0, count: length)
18*fe5cfb17STomasz Sapeta   let status = SecRandomCopyBytes(kSecRandomDefault, length, &bytes)
19*fe5cfb17STomasz Sapeta 
20*fe5cfb17STomasz Sapeta   guard status == errSecSuccess else {
21*fe5cfb17STomasz Sapeta     throw FailedGeneratingRandomBytesException(status)
22*fe5cfb17STomasz Sapeta   }
23*fe5cfb17STomasz Sapeta   return Data(bytes).base64EncodedString()
24*fe5cfb17STomasz Sapeta }
25*fe5cfb17STomasz Sapeta 
26*fe5cfb17STomasz Sapeta private class FailedGeneratingRandomBytesException: GenericException<OSStatus> {
27*fe5cfb17STomasz Sapeta   override var reason: String {
28*fe5cfb17STomasz Sapeta     "Generating random bytes has failed with OSStatus code: \(param)"
29*fe5cfb17STomasz Sapeta   }
30*fe5cfb17STomasz Sapeta }
31