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