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